ipsec.c revision 167820
1/*	$FreeBSD: head/sys/netipsec/ipsec.c 167820 2007-03-22 22:25:25Z sam $	*/
2/*	$KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $	*/
3
4/*-
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 *    may be used to endorse or promote products derived from this software
18 *    without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33/*
34 * IPsec controller part.
35 */
36
37#include "opt_inet.h"
38#include "opt_inet6.h"
39#include "opt_ipsec.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/malloc.h>
44#include <sys/mbuf.h>
45#include <sys/domain.h>
46#include <sys/priv.h>
47#include <sys/protosw.h>
48#include <sys/socket.h>
49#include <sys/socketvar.h>
50#include <sys/errno.h>
51#include <sys/time.h>
52#include <sys/kernel.h>
53#include <sys/syslog.h>
54#include <sys/sysctl.h>
55#include <sys/proc.h>
56
57#include <net/if.h>
58#include <net/route.h>
59
60#include <netinet/in.h>
61#include <netinet/in_systm.h>
62#include <netinet/ip.h>
63#include <netinet/ip_var.h>
64#include <netinet/in_var.h>
65#include <netinet/udp.h>
66#include <netinet/udp_var.h>
67#include <netinet/tcp.h>
68#include <netinet/udp.h>
69
70#include <netinet/ip6.h>
71#ifdef INET6
72#include <netinet6/ip6_var.h>
73#endif
74#include <netinet/in_pcb.h>
75#ifdef INET6
76#include <netinet/icmp6.h>
77#endif
78
79#include <netipsec/ipsec.h>
80#ifdef INET6
81#include <netipsec/ipsec6.h>
82#endif
83#include <netipsec/ah_var.h>
84#include <netipsec/esp_var.h>
85#include <netipsec/ipcomp.h>		/*XXX*/
86#include <netipsec/ipcomp_var.h>
87
88#include <netipsec/key.h>
89#include <netipsec/keydb.h>
90#include <netipsec/key_debug.h>
91
92#include <netipsec/xform.h>
93
94#include <machine/in_cksum.h>
95
96#include <opencrypto/cryptodev.h>
97
98#ifdef IPSEC_DEBUG
99int ipsec_debug = 1;
100#else
101int ipsec_debug = 0;
102#endif
103
104/* NB: name changed so netstat doesn't use it */
105struct newipsecstat newipsecstat;
106int ip4_ah_offsetmask = 0;	/* maybe IP_DF? */
107int ip4_ipsec_dfbit = 0;	/* DF bit on encap. 0: clear 1: set 2: copy */
108int ip4_esp_trans_deflev = IPSEC_LEVEL_USE;
109int ip4_esp_net_deflev = IPSEC_LEVEL_USE;
110int ip4_ah_trans_deflev = IPSEC_LEVEL_USE;
111int ip4_ah_net_deflev = IPSEC_LEVEL_USE;
112struct secpolicy ip4_def_policy;
113int ip4_ipsec_ecn = 0;		/* ECN ignore(-1)/forbidden(0)/allowed(1) */
114int ip4_esp_randpad = -1;
115/*
116 * Crypto support requirements:
117 *
118 *  1	require hardware support
119 * -1	require software support
120 *  0	take anything
121 */
122int	crypto_support = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
123
124SYSCTL_DECL(_net_inet_ipsec);
125
126/* net.inet.ipsec */
127SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_POLICY,
128	def_policy, CTLFLAG_RW,	&ip4_def_policy.policy,	0, "");
129SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
130	CTLFLAG_RW, &ip4_esp_trans_deflev,	0, "");
131SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
132	CTLFLAG_RW, &ip4_esp_net_deflev,	0, "");
133SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
134	CTLFLAG_RW, &ip4_ah_trans_deflev,	0, "");
135SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
136	CTLFLAG_RW, &ip4_ah_net_deflev,	0, "");
137SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS,
138	ah_cleartos, CTLFLAG_RW,	&ah_cleartos,	0, "");
139SYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_OFFSETMASK,
140	ah_offsetmask, CTLFLAG_RW,	&ip4_ah_offsetmask,	0, "");
141SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT,
142	dfbit, CTLFLAG_RW,	&ip4_ipsec_dfbit,	0, "");
143SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN,
144	ecn, CTLFLAG_RW,	&ip4_ipsec_ecn,	0, "");
145SYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEBUG,
146	debug, CTLFLAG_RW,	&ipsec_debug,	0, "");
147SYSCTL_INT(_net_inet_ipsec, IPSECCTL_ESP_RANDPAD,
148	esp_randpad, CTLFLAG_RW,	&ip4_esp_randpad,	0, "");
149SYSCTL_INT(_net_inet_ipsec, OID_AUTO,
150	crypto_support,	CTLFLAG_RW,	&crypto_support,0, "");
151SYSCTL_STRUCT(_net_inet_ipsec, OID_AUTO,
152	ipsecstats,	CTLFLAG_RD,	&newipsecstat,	newipsecstat, "");
153
154#ifdef REGRESSION
155/*
156 * When set to 1, IPsec will send packets with the same sequence number.
157 * This allows to verify if the other side has proper replay attacks detection.
158 */
159int ipsec_replay = 0;
160SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_replay, CTLFLAG_RW, &ipsec_replay, 0,
161    "Emulate replay attack");
162/*
163 * When set 1, IPsec will send packets with corrupted HMAC.
164 * This allows to verify if the other side properly detects modified packets.
165 */
166int ipsec_integrity = 0;
167SYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_integrity, CTLFLAG_RW,
168    &ipsec_integrity, 0, "Emulate man-in-the-middle attack");
169#endif
170
171#ifdef INET6
172int ip6_esp_trans_deflev = IPSEC_LEVEL_USE;
173int ip6_esp_net_deflev = IPSEC_LEVEL_USE;
174int ip6_ah_trans_deflev = IPSEC_LEVEL_USE;
175int ip6_ah_net_deflev = IPSEC_LEVEL_USE;
176int ip6_ipsec_ecn = 0;		/* ECN ignore(-1)/forbidden(0)/allowed(1) */
177int ip6_esp_randpad = -1;
178
179SYSCTL_DECL(_net_inet6_ipsec6);
180
181/* net.inet6.ipsec6 */
182#ifdef COMPAT_KAME
183SYSCTL_OID(_net_inet6_ipsec6, IPSECCTL_STATS, stats, CTLFLAG_RD,
184	0,0, compat_ipsecstats_sysctl, "S", "");
185#endif /* COMPAT_KAME */
186SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY,
187	def_policy, CTLFLAG_RW,	&ip4_def_policy.policy,	0, "");
188SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
189	CTLFLAG_RW, &ip6_esp_trans_deflev,	0, "");
190SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
191	CTLFLAG_RW, &ip6_esp_net_deflev,	0, "");
192SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
193	CTLFLAG_RW, &ip6_ah_trans_deflev,	0, "");
194SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
195	CTLFLAG_RW, &ip6_ah_net_deflev,	0, "");
196SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN,
197	ecn, CTLFLAG_RW,	&ip6_ipsec_ecn,	0, "");
198SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEBUG,
199	debug, CTLFLAG_RW,	&ipsec_debug,	0, "");
200SYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ESP_RANDPAD,
201	esp_randpad, CTLFLAG_RW,	&ip6_esp_randpad,	0, "");
202#endif /* INET6 */
203
204static int ipsec4_setspidx_inpcb __P((struct mbuf *, struct inpcb *pcb));
205#ifdef INET6
206static int ipsec6_setspidx_in6pcb __P((struct mbuf *, struct in6pcb *pcb));
207#endif
208static int ipsec_setspidx __P((struct mbuf *, struct secpolicyindex *, int));
209static void ipsec4_get_ulp __P((struct mbuf *m, struct secpolicyindex *, int));
210static int ipsec4_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *));
211#ifdef INET6
212static void ipsec6_get_ulp __P((struct mbuf *m, struct secpolicyindex *, int));
213static int ipsec6_setspidx_ipaddr __P((struct mbuf *, struct secpolicyindex *));
214#endif
215static void ipsec_delpcbpolicy __P((struct inpcbpolicy *));
216static struct secpolicy *ipsec_deepcopy_policy __P((struct secpolicy *src));
217static int ipsec_set_policy __P((struct secpolicy **pcb_sp,
218	int optname, caddr_t request, size_t len, int priv));
219static int ipsec_get_policy __P((struct secpolicy *pcb_sp, struct mbuf **mp));
220static void vshiftl __P((unsigned char *, int, int));
221static size_t ipsec_hdrsiz __P((struct secpolicy *));
222
223MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolicy", "inpcb-resident ipsec policy");
224
225/*
226 * Return a held reference to the default SP.
227 */
228static struct secpolicy *
229key_allocsp_default(const char* where, int tag)
230{
231	struct secpolicy *sp;
232
233	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
234		printf("DP key_allocsp_default from %s:%u\n", where, tag));
235
236	sp = &ip4_def_policy;
237	if (sp->policy != IPSEC_POLICY_DISCARD &&
238	    sp->policy != IPSEC_POLICY_NONE) {
239		ipseclog((LOG_INFO, "fixed system default policy: %d->%d\n",
240		    sp->policy, IPSEC_POLICY_NONE));
241		sp->policy = IPSEC_POLICY_NONE;
242	}
243	key_addref(sp);
244
245	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
246		printf("DP key_allocsp_default returns SP:%p (%u)\n",
247			sp, sp->refcnt));
248	return sp;
249}
250#define	KEY_ALLOCSP_DEFAULT() \
251	key_allocsp_default(__FILE__, __LINE__)
252
253/*
254 * For OUTBOUND packet having a socket. Searching SPD for packet,
255 * and return a pointer to SP.
256 * OUT:	NULL:	no apropreate SP found, the following value is set to error.
257 *		0	: bypass
258 *		EACCES	: discard packet.
259 *		ENOENT	: ipsec_acquire() in progress, maybe.
260 *		others	: error occured.
261 *	others:	a pointer to SP
262 *
263 * NOTE: IPv6 mapped adddress concern is implemented here.
264 */
265struct secpolicy *
266ipsec_getpolicy(struct tdb_ident *tdbi, u_int dir)
267{
268	struct secpolicy *sp;
269
270	IPSEC_ASSERT(tdbi != NULL, ("null tdbi"));
271	IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
272		("invalid direction %u", dir));
273
274	sp = KEY_ALLOCSP2(tdbi->spi, &tdbi->dst, tdbi->proto, dir);
275	if (sp == NULL)			/*XXX????*/
276		sp = KEY_ALLOCSP_DEFAULT();
277	IPSEC_ASSERT(sp != NULL, ("null SP"));
278	return sp;
279}
280
281/*
282 * For OUTBOUND packet having a socket. Searching SPD for packet,
283 * and return a pointer to SP.
284 * OUT:	NULL:	no apropreate SP found, the following value is set to error.
285 *		0	: bypass
286 *		EACCES	: discard packet.
287 *		ENOENT	: ipsec_acquire() in progress, maybe.
288 *		others	: error occured.
289 *	others:	a pointer to SP
290 *
291 * NOTE: IPv6 mapped adddress concern is implemented here.
292 */
293struct secpolicy *
294ipsec_getpolicybysock(m, dir, inp, error)
295	struct mbuf *m;
296	u_int dir;
297	struct inpcb *inp;
298	int *error;
299{
300	struct inpcbpolicy *pcbsp = NULL;
301	struct secpolicy *currsp = NULL;	/* policy on socket */
302	struct secpolicy *sp;
303
304	IPSEC_ASSERT(m != NULL, ("null mbuf"));
305	IPSEC_ASSERT(inp != NULL, ("null inpcb"));
306	IPSEC_ASSERT(error != NULL, ("null error"));
307	IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
308		("invalid direction %u", dir));
309
310	/* set spidx in pcb */
311	if (inp->inp_vflag & INP_IPV6PROTO) {
312#ifdef INET6
313		*error = ipsec6_setspidx_in6pcb(m, inp);
314		pcbsp = inp->in6p_sp;
315#else
316		*error = EINVAL;		/* should not happen */
317#endif
318	} else {
319		*error = ipsec4_setspidx_inpcb(m, inp);
320		pcbsp = inp->inp_sp;
321	}
322	if (*error)
323		return NULL;
324
325	IPSEC_ASSERT(pcbsp != NULL, ("null pcbsp"));
326	switch (dir) {
327	case IPSEC_DIR_INBOUND:
328		currsp = pcbsp->sp_in;
329		break;
330	case IPSEC_DIR_OUTBOUND:
331		currsp = pcbsp->sp_out;
332		break;
333	}
334	IPSEC_ASSERT(currsp != NULL, ("null currsp"));
335
336	if (pcbsp->priv) {			/* when privilieged socket */
337		switch (currsp->policy) {
338		case IPSEC_POLICY_BYPASS:
339		case IPSEC_POLICY_IPSEC:
340			key_addref(currsp);
341			sp = currsp;
342			break;
343
344		case IPSEC_POLICY_ENTRUST:
345			/* look for a policy in SPD */
346			sp = KEY_ALLOCSP(&currsp->spidx, dir);
347			if (sp == NULL)		/* no SP found */
348				sp = KEY_ALLOCSP_DEFAULT();
349			break;
350
351		default:
352			ipseclog((LOG_ERR, "%s: Invalid policy for PCB %d\n",
353				__func__, currsp->policy));
354			*error = EINVAL;
355			return NULL;
356		}
357	} else {				/* unpriv, SPD has policy */
358		sp = KEY_ALLOCSP(&currsp->spidx, dir);
359		if (sp == NULL) {		/* no SP found */
360			switch (currsp->policy) {
361			case IPSEC_POLICY_BYPASS:
362				ipseclog((LOG_ERR, "%s: Illegal policy for "
363					"non-priviliged defined %d\n",
364					__func__, currsp->policy));
365				*error = EINVAL;
366				return NULL;
367
368			case IPSEC_POLICY_ENTRUST:
369				sp = KEY_ALLOCSP_DEFAULT();
370				break;
371
372			case IPSEC_POLICY_IPSEC:
373				key_addref(currsp);
374				sp = currsp;
375				break;
376
377			default:
378				ipseclog((LOG_ERR, "%s: Invalid policy for "
379					"PCB %d\n", __func__, currsp->policy));
380				*error = EINVAL;
381				return NULL;
382			}
383		}
384	}
385	IPSEC_ASSERT(sp != NULL,
386		("null SP (priv %u policy %u", pcbsp->priv, currsp->policy));
387	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
388		printf("DP %s (priv %u policy %u) allocate SP:%p (refcnt %u)\n",
389			__func__, pcbsp->priv, currsp->policy, sp, sp->refcnt));
390	return sp;
391}
392
393/*
394 * For FORWADING packet or OUTBOUND without a socket. Searching SPD for packet,
395 * and return a pointer to SP.
396 * OUT:	positive: a pointer to the entry for security policy leaf matched.
397 *	NULL:	no apropreate SP found, the following value is set to error.
398 *		0	: bypass
399 *		EACCES	: discard packet.
400 *		ENOENT	: ipsec_acquire() in progress, maybe.
401 *		others	: error occured.
402 */
403struct secpolicy *
404ipsec_getpolicybyaddr(m, dir, flag, error)
405	struct mbuf *m;
406	u_int dir;
407	int flag;
408	int *error;
409{
410	struct secpolicyindex spidx;
411	struct secpolicy *sp;
412
413	IPSEC_ASSERT(m != NULL, ("null mbuf"));
414	IPSEC_ASSERT(error != NULL, ("null error"));
415	IPSEC_ASSERT(dir == IPSEC_DIR_INBOUND || dir == IPSEC_DIR_OUTBOUND,
416		("invalid direction %u", dir));
417
418	sp = NULL;
419	if (key_havesp(dir)) {
420		/* Make an index to look for a policy. */
421		*error = ipsec_setspidx(m, &spidx,
422					(flag & IP_FORWARDING) ? 0 : 1);
423		if (*error != 0) {
424			DPRINTF(("%s: setpidx failed, dir %u flag %u\n",
425				__func__, dir, flag));
426			return NULL;
427		}
428		spidx.dir = dir;
429
430		sp = KEY_ALLOCSP(&spidx, dir);
431	}
432	if (sp == NULL)			/* no SP found, use system default */
433		sp = KEY_ALLOCSP_DEFAULT();
434	IPSEC_ASSERT(sp != NULL, ("null SP"));
435	return sp;
436}
437
438struct secpolicy *
439ipsec4_checkpolicy(m, dir, flag, error, inp)
440	struct mbuf *m;
441	u_int dir, flag;
442	int *error;
443	struct inpcb *inp;
444{
445	struct secpolicy *sp;
446
447	*error = 0;
448	if (inp == NULL)
449		sp = ipsec_getpolicybyaddr(m, dir, flag, error);
450	else
451		sp = ipsec_getpolicybysock(m, dir, inp, error);
452	if (sp == NULL) {
453		IPSEC_ASSERT(*error != 0, ("getpolicy failed w/o error"));
454		newipsecstat.ips_out_inval++;
455		return NULL;
456	}
457	IPSEC_ASSERT(*error == 0, ("sp w/ error set to %u", *error));
458	switch (sp->policy) {
459	case IPSEC_POLICY_ENTRUST:
460	default:
461		printf("%s: invalid policy %u\n", __func__, sp->policy);
462		/* fall thru... */
463	case IPSEC_POLICY_DISCARD:
464		newipsecstat.ips_out_polvio++;
465		*error = -EINVAL;	/* packet is discarded by caller */
466		break;
467	case IPSEC_POLICY_BYPASS:
468	case IPSEC_POLICY_NONE:
469		KEY_FREESP(&sp);
470		sp = NULL;		/* NB: force NULL result */
471		break;
472	case IPSEC_POLICY_IPSEC:
473		if (sp->req == NULL)	/* acquire an SA */
474			*error = key_spdacquire(sp);
475		break;
476	}
477	if (*error != 0) {
478		KEY_FREESP(&sp);
479		sp = NULL;
480	}
481	return sp;
482}
483
484static int
485ipsec4_setspidx_inpcb(m, pcb)
486	struct mbuf *m;
487	struct inpcb *pcb;
488{
489	int error;
490
491	IPSEC_ASSERT(pcb != NULL, ("null pcb"));
492	IPSEC_ASSERT(pcb->inp_sp != NULL, ("null inp_sp"));
493	IPSEC_ASSERT(pcb->inp_sp->sp_out != NULL && pcb->inp_sp->sp_in != NULL,
494		("null sp_in || sp_out"));
495
496	error = ipsec_setspidx(m, &pcb->inp_sp->sp_in->spidx, 1);
497	if (error == 0) {
498		pcb->inp_sp->sp_in->spidx.dir = IPSEC_DIR_INBOUND;
499		pcb->inp_sp->sp_out->spidx = pcb->inp_sp->sp_in->spidx;
500		pcb->inp_sp->sp_out->spidx.dir = IPSEC_DIR_OUTBOUND;
501	} else {
502		bzero(&pcb->inp_sp->sp_in->spidx,
503			sizeof (pcb->inp_sp->sp_in->spidx));
504		bzero(&pcb->inp_sp->sp_out->spidx,
505			sizeof (pcb->inp_sp->sp_in->spidx));
506	}
507	return error;
508}
509
510#ifdef INET6
511static int
512ipsec6_setspidx_in6pcb(m, pcb)
513	struct mbuf *m;
514	struct in6pcb *pcb;
515{
516	struct secpolicyindex *spidx;
517	int error;
518
519	IPSEC_ASSERT(pcb != NULL, ("null pcb"));
520	IPSEC_ASSERT(pcb->in6p_sp != NULL, ("null inp_sp"));
521	IPSEC_ASSERT(pcb->in6p_sp->sp_out != NULL && pcb->in6p_sp->sp_in != NULL,
522		("null sp_in || sp_out"));
523
524	bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
525	bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
526
527	spidx = &pcb->in6p_sp->sp_in->spidx;
528	error = ipsec_setspidx(m, spidx, 1);
529	if (error)
530		goto bad;
531	spidx->dir = IPSEC_DIR_INBOUND;
532
533	spidx = &pcb->in6p_sp->sp_out->spidx;
534	error = ipsec_setspidx(m, spidx, 1);
535	if (error)
536		goto bad;
537	spidx->dir = IPSEC_DIR_OUTBOUND;
538
539	return 0;
540
541bad:
542	bzero(&pcb->in6p_sp->sp_in->spidx, sizeof(*spidx));
543	bzero(&pcb->in6p_sp->sp_out->spidx, sizeof(*spidx));
544	return error;
545}
546#endif
547
548/*
549 * configure security policy index (src/dst/proto/sport/dport)
550 * by looking at the content of mbuf.
551 * the caller is responsible for error recovery (like clearing up spidx).
552 */
553static int
554ipsec_setspidx(m, spidx, needport)
555	struct mbuf *m;
556	struct secpolicyindex *spidx;
557	int needport;
558{
559	struct ip *ip = NULL;
560	struct ip ipbuf;
561	u_int v;
562	struct mbuf *n;
563	int len;
564	int error;
565
566	IPSEC_ASSERT(m != NULL, ("null mbuf"));
567
568	/*
569	 * validate m->m_pkthdr.len.  we see incorrect length if we
570	 * mistakenly call this function with inconsistent mbuf chain
571	 * (like 4.4BSD tcp/udp processing).  XXX should we panic here?
572	 */
573	len = 0;
574	for (n = m; n; n = n->m_next)
575		len += n->m_len;
576	if (m->m_pkthdr.len != len) {
577		KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
578			printf("%s: pkthdr len(%d) mismatch (%d), ignored.\n",
579				__func__, len, m->m_pkthdr.len));
580		return EINVAL;
581	}
582
583	if (m->m_pkthdr.len < sizeof(struct ip)) {
584		KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
585			printf("%s: pkthdr len(%d) too small (v4), ignored.\n",
586			    __func__, m->m_pkthdr.len));
587		return EINVAL;
588	}
589
590	if (m->m_len >= sizeof(*ip))
591		ip = mtod(m, struct ip *);
592	else {
593		m_copydata(m, 0, sizeof(ipbuf), (caddr_t)&ipbuf);
594		ip = &ipbuf;
595	}
596#ifdef _IP_VHL
597	v = _IP_VHL_V(ip->ip_vhl);
598#else
599	v = ip->ip_v;
600#endif
601	switch (v) {
602	case 4:
603		error = ipsec4_setspidx_ipaddr(m, spidx);
604		if (error)
605			return error;
606		ipsec4_get_ulp(m, spidx, needport);
607		return 0;
608#ifdef INET6
609	case 6:
610		if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) {
611			KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
612				printf("%s: pkthdr len(%d) too small (v6), "
613				"ignored\n", __func__, m->m_pkthdr.len));
614			return EINVAL;
615		}
616		error = ipsec6_setspidx_ipaddr(m, spidx);
617		if (error)
618			return error;
619		ipsec6_get_ulp(m, spidx, needport);
620		return 0;
621#endif
622	default:
623		KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
624			printf("%s: " "unknown IP version %u, ignored.\n",
625				__func__, v));
626		return EINVAL;
627	}
628}
629
630static void
631ipsec4_get_ulp(struct mbuf *m, struct secpolicyindex *spidx, int needport)
632{
633	u_int8_t nxt;
634	int off;
635
636	/* sanity check */
637	IPSEC_ASSERT(m != NULL, ("null mbuf"));
638	IPSEC_ASSERT(m->m_pkthdr.len >= sizeof(struct ip),("packet too short"));
639
640	/* NB: ip_input() flips it into host endian XXX need more checking */
641	if (m->m_len < sizeof (struct ip)) {
642		struct ip *ip = mtod(m, struct ip *);
643		if (ip->ip_off & (IP_MF | IP_OFFMASK))
644			goto done;
645#ifdef _IP_VHL
646		off = _IP_VHL_HL(ip->ip_vhl) << 2;
647#else
648		off = ip->ip_hl << 2;
649#endif
650		nxt = ip->ip_p;
651	} else {
652		struct ip ih;
653
654		m_copydata(m, 0, sizeof (struct ip), (caddr_t) &ih);
655		if (ih.ip_off & (IP_MF | IP_OFFMASK))
656			goto done;
657#ifdef _IP_VHL
658		off = _IP_VHL_HL(ih.ip_vhl) << 2;
659#else
660		off = ih.ip_hl << 2;
661#endif
662		nxt = ih.ip_p;
663	}
664
665	while (off < m->m_pkthdr.len) {
666		struct ip6_ext ip6e;
667		struct tcphdr th;
668		struct udphdr uh;
669
670		switch (nxt) {
671		case IPPROTO_TCP:
672			spidx->ul_proto = nxt;
673			if (!needport)
674				goto done_proto;
675			if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
676				goto done;
677			m_copydata(m, off, sizeof (th), (caddr_t) &th);
678			spidx->src.sin.sin_port = th.th_sport;
679			spidx->dst.sin.sin_port = th.th_dport;
680			return;
681		case IPPROTO_UDP:
682			spidx->ul_proto = nxt;
683			if (!needport)
684				goto done_proto;
685			if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
686				goto done;
687			m_copydata(m, off, sizeof (uh), (caddr_t) &uh);
688			spidx->src.sin.sin_port = uh.uh_sport;
689			spidx->dst.sin.sin_port = uh.uh_dport;
690			return;
691		case IPPROTO_AH:
692			if (off + sizeof(ip6e) > m->m_pkthdr.len)
693				goto done;
694			/* XXX sigh, this works but is totally bogus */
695			m_copydata(m, off, sizeof(ip6e), (caddr_t) &ip6e);
696			off += (ip6e.ip6e_len + 2) << 2;
697			nxt = ip6e.ip6e_nxt;
698			break;
699		case IPPROTO_ICMP:
700		default:
701			/* XXX intermediate headers??? */
702			spidx->ul_proto = nxt;
703			goto done_proto;
704		}
705	}
706done:
707	spidx->ul_proto = IPSEC_ULPROTO_ANY;
708done_proto:
709	spidx->src.sin.sin_port = IPSEC_PORT_ANY;
710	spidx->dst.sin.sin_port = IPSEC_PORT_ANY;
711}
712
713/* assumes that m is sane */
714static int
715ipsec4_setspidx_ipaddr(struct mbuf *m, struct secpolicyindex *spidx)
716{
717	static const struct sockaddr_in template = {
718		sizeof (struct sockaddr_in),
719		AF_INET,
720		0, { 0 }, { 0, 0, 0, 0, 0, 0, 0, 0 }
721	};
722
723	spidx->src.sin = template;
724	spidx->dst.sin = template;
725
726	if (m->m_len < sizeof (struct ip)) {
727		m_copydata(m, offsetof(struct ip, ip_src),
728			   sizeof (struct  in_addr),
729			   (caddr_t) &spidx->src.sin.sin_addr);
730		m_copydata(m, offsetof(struct ip, ip_dst),
731			   sizeof (struct  in_addr),
732			   (caddr_t) &spidx->dst.sin.sin_addr);
733	} else {
734		struct ip *ip = mtod(m, struct ip *);
735		spidx->src.sin.sin_addr = ip->ip_src;
736		spidx->dst.sin.sin_addr = ip->ip_dst;
737	}
738
739	spidx->prefs = sizeof(struct in_addr) << 3;
740	spidx->prefd = sizeof(struct in_addr) << 3;
741
742	return 0;
743}
744
745#ifdef INET6
746static void
747ipsec6_get_ulp(m, spidx, needport)
748	struct mbuf *m;
749	struct secpolicyindex *spidx;
750	int needport;
751{
752	int off, nxt;
753	struct tcphdr th;
754	struct udphdr uh;
755
756	/* sanity check */
757	if (m == NULL)
758		panic("%s: NULL pointer was passed.\n", __func__);
759
760	KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
761		printf("%s:\n", __func__); kdebug_mbuf(m));
762
763	/* set default */
764	spidx->ul_proto = IPSEC_ULPROTO_ANY;
765	((struct sockaddr_in6 *)&spidx->src)->sin6_port = IPSEC_PORT_ANY;
766	((struct sockaddr_in6 *)&spidx->dst)->sin6_port = IPSEC_PORT_ANY;
767
768	nxt = -1;
769	off = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt);
770	if (off < 0 || m->m_pkthdr.len < off)
771		return;
772
773	switch (nxt) {
774	case IPPROTO_TCP:
775		spidx->ul_proto = nxt;
776		if (!needport)
777			break;
778		if (off + sizeof(struct tcphdr) > m->m_pkthdr.len)
779			break;
780		m_copydata(m, off, sizeof(th), (caddr_t)&th);
781		((struct sockaddr_in6 *)&spidx->src)->sin6_port = th.th_sport;
782		((struct sockaddr_in6 *)&spidx->dst)->sin6_port = th.th_dport;
783		break;
784	case IPPROTO_UDP:
785		spidx->ul_proto = nxt;
786		if (!needport)
787			break;
788		if (off + sizeof(struct udphdr) > m->m_pkthdr.len)
789			break;
790		m_copydata(m, off, sizeof(uh), (caddr_t)&uh);
791		((struct sockaddr_in6 *)&spidx->src)->sin6_port = uh.uh_sport;
792		((struct sockaddr_in6 *)&spidx->dst)->sin6_port = uh.uh_dport;
793		break;
794	case IPPROTO_ICMPV6:
795	default:
796		/* XXX intermediate headers??? */
797		spidx->ul_proto = nxt;
798		break;
799	}
800}
801
802/* assumes that m is sane */
803static int
804ipsec6_setspidx_ipaddr(m, spidx)
805	struct mbuf *m;
806	struct secpolicyindex *spidx;
807{
808	struct ip6_hdr *ip6 = NULL;
809	struct ip6_hdr ip6buf;
810	struct sockaddr_in6 *sin6;
811
812	if (m->m_len >= sizeof(*ip6))
813		ip6 = mtod(m, struct ip6_hdr *);
814	else {
815		m_copydata(m, 0, sizeof(ip6buf), (caddr_t)&ip6buf);
816		ip6 = &ip6buf;
817	}
818
819	sin6 = (struct sockaddr_in6 *)&spidx->src;
820	bzero(sin6, sizeof(*sin6));
821	sin6->sin6_family = AF_INET6;
822	sin6->sin6_len = sizeof(struct sockaddr_in6);
823	bcopy(&ip6->ip6_src, &sin6->sin6_addr, sizeof(ip6->ip6_src));
824	if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src)) {
825		sin6->sin6_addr.s6_addr16[1] = 0;
826		sin6->sin6_scope_id = ntohs(ip6->ip6_src.s6_addr16[1]);
827	}
828	spidx->prefs = sizeof(struct in6_addr) << 3;
829
830	sin6 = (struct sockaddr_in6 *)&spidx->dst;
831	bzero(sin6, sizeof(*sin6));
832	sin6->sin6_family = AF_INET6;
833	sin6->sin6_len = sizeof(struct sockaddr_in6);
834	bcopy(&ip6->ip6_dst, &sin6->sin6_addr, sizeof(ip6->ip6_dst));
835	if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst)) {
836		sin6->sin6_addr.s6_addr16[1] = 0;
837		sin6->sin6_scope_id = ntohs(ip6->ip6_dst.s6_addr16[1]);
838	}
839	spidx->prefd = sizeof(struct in6_addr) << 3;
840
841	return 0;
842}
843#endif
844
845static void
846ipsec_delpcbpolicy(p)
847	struct inpcbpolicy *p;
848{
849	free(p, M_IPSEC_INPCB);
850}
851
852/* initialize policy in PCB */
853int
854ipsec_init_policy(so, pcb_sp)
855	struct socket *so;
856	struct inpcbpolicy **pcb_sp;
857{
858	struct inpcbpolicy *new;
859
860	/* sanity check. */
861	if (so == NULL || pcb_sp == NULL)
862		panic("%s: NULL pointer was passed.\n", __func__);
863
864	new = (struct inpcbpolicy *) malloc(sizeof(struct inpcbpolicy),
865					    M_IPSEC_INPCB, M_NOWAIT|M_ZERO);
866	if (new == NULL) {
867		ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
868		return ENOBUFS;
869	}
870
871	new->priv = IPSEC_IS_PRIVILEGED_SO(so);
872
873	if ((new->sp_in = KEY_NEWSP()) == NULL) {
874		ipsec_delpcbpolicy(new);
875		return ENOBUFS;
876	}
877	new->sp_in->state = IPSEC_SPSTATE_ALIVE;
878	new->sp_in->policy = IPSEC_POLICY_ENTRUST;
879
880	if ((new->sp_out = KEY_NEWSP()) == NULL) {
881		KEY_FREESP(&new->sp_in);
882		ipsec_delpcbpolicy(new);
883		return ENOBUFS;
884	}
885	new->sp_out->state = IPSEC_SPSTATE_ALIVE;
886	new->sp_out->policy = IPSEC_POLICY_ENTRUST;
887
888	*pcb_sp = new;
889
890	return 0;
891}
892
893/* copy old ipsec policy into new */
894int
895ipsec_copy_policy(old, new)
896	struct inpcbpolicy *old, *new;
897{
898	struct secpolicy *sp;
899
900	sp = ipsec_deepcopy_policy(old->sp_in);
901	if (sp) {
902		KEY_FREESP(&new->sp_in);
903		new->sp_in = sp;
904	} else
905		return ENOBUFS;
906
907	sp = ipsec_deepcopy_policy(old->sp_out);
908	if (sp) {
909		KEY_FREESP(&new->sp_out);
910		new->sp_out = sp;
911	} else
912		return ENOBUFS;
913
914	new->priv = old->priv;
915
916	return 0;
917}
918
919struct ipsecrequest *
920ipsec_newisr(void)
921{
922	struct ipsecrequest *p;
923
924	p = malloc(sizeof(struct ipsecrequest), M_IPSEC_SR, M_NOWAIT|M_ZERO);
925	if (p != NULL)
926		IPSECREQUEST_LOCK_INIT(p);
927	return p;
928}
929
930void
931ipsec_delisr(struct ipsecrequest *p)
932{
933	IPSECREQUEST_LOCK_DESTROY(p);
934	free(p, M_IPSEC_SR);
935}
936
937/* deep-copy a policy in PCB */
938static struct secpolicy *
939ipsec_deepcopy_policy(src)
940	struct secpolicy *src;
941{
942	struct ipsecrequest *newchain = NULL;
943	struct ipsecrequest *p;
944	struct ipsecrequest **q;
945	struct ipsecrequest *r;
946	struct secpolicy *dst;
947
948	if (src == NULL)
949		return NULL;
950	dst = KEY_NEWSP();
951	if (dst == NULL)
952		return NULL;
953
954	/*
955	 * deep-copy IPsec request chain.  This is required since struct
956	 * ipsecrequest is not reference counted.
957	 */
958	q = &newchain;
959	for (p = src->req; p; p = p->next) {
960		*q = ipsec_newisr();
961		if (*q == NULL)
962			goto fail;
963		(*q)->saidx.proto = p->saidx.proto;
964		(*q)->saidx.mode = p->saidx.mode;
965		(*q)->level = p->level;
966		(*q)->saidx.reqid = p->saidx.reqid;
967
968		bcopy(&p->saidx.src, &(*q)->saidx.src, sizeof((*q)->saidx.src));
969		bcopy(&p->saidx.dst, &(*q)->saidx.dst, sizeof((*q)->saidx.dst));
970
971		(*q)->sp = dst;
972
973		q = &((*q)->next);
974	}
975
976	dst->req = newchain;
977	dst->state = src->state;
978	dst->policy = src->policy;
979	/* do not touch the refcnt fields */
980
981	return dst;
982
983fail:
984	for (p = newchain; p; p = r) {
985		r = p->next;
986		ipsec_delisr(p);
987		p = NULL;
988	}
989	return NULL;
990}
991
992/* set policy and ipsec request if present. */
993static int
994ipsec_set_policy(pcb_sp, optname, request, len, priv)
995	struct secpolicy **pcb_sp;
996	int optname;
997	caddr_t request;
998	size_t len;
999	int priv;
1000{
1001	struct sadb_x_policy *xpl;
1002	struct secpolicy *newsp = NULL;
1003	int error;
1004
1005	/* sanity check. */
1006	if (pcb_sp == NULL || *pcb_sp == NULL || request == NULL)
1007		return EINVAL;
1008	if (len < sizeof(*xpl))
1009		return EINVAL;
1010	xpl = (struct sadb_x_policy *)request;
1011
1012	KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1013		printf("%s: passed policy\n", __func__);
1014		kdebug_sadb_x_policy((struct sadb_ext *)xpl));
1015
1016	/* check policy type */
1017	/* ipsec_set_policy() accepts IPSEC, ENTRUST and BYPASS. */
1018	if (xpl->sadb_x_policy_type == IPSEC_POLICY_DISCARD
1019	 || xpl->sadb_x_policy_type == IPSEC_POLICY_NONE)
1020		return EINVAL;
1021
1022	/* check privileged socket */
1023	if (priv == 0 && xpl->sadb_x_policy_type == IPSEC_POLICY_BYPASS)
1024		return EACCES;
1025
1026	/* allocation new SP entry */
1027	if ((newsp = key_msg2sp(xpl, len, &error)) == NULL)
1028		return error;
1029
1030	newsp->state = IPSEC_SPSTATE_ALIVE;
1031
1032	/* clear old SP and set new SP */
1033	KEY_FREESP(pcb_sp);
1034	*pcb_sp = newsp;
1035	KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1036		printf("%s: new policy\n", __func__);
1037		kdebug_secpolicy(newsp));
1038
1039	return 0;
1040}
1041
1042static int
1043ipsec_get_policy(pcb_sp, mp)
1044	struct secpolicy *pcb_sp;
1045	struct mbuf **mp;
1046{
1047
1048	/* sanity check. */
1049	if (pcb_sp == NULL || mp == NULL)
1050		return EINVAL;
1051
1052	*mp = key_sp2msg(pcb_sp);
1053	if (!*mp) {
1054		ipseclog((LOG_DEBUG, "%s: No more memory.\n", __func__));
1055		return ENOBUFS;
1056	}
1057
1058	(*mp)->m_type = MT_DATA;
1059	KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1060		printf("%s:\n", __func__); kdebug_mbuf(*mp));
1061
1062	return 0;
1063}
1064
1065int
1066ipsec4_set_policy(inp, optname, request, len, priv)
1067	struct inpcb *inp;
1068	int optname;
1069	caddr_t request;
1070	size_t len;
1071	int priv;
1072{
1073	struct sadb_x_policy *xpl;
1074	struct secpolicy **pcb_sp;
1075
1076	/* sanity check. */
1077	if (inp == NULL || request == NULL)
1078		return EINVAL;
1079	if (len < sizeof(*xpl))
1080		return EINVAL;
1081	xpl = (struct sadb_x_policy *)request;
1082
1083	/* select direction */
1084	switch (xpl->sadb_x_policy_dir) {
1085	case IPSEC_DIR_INBOUND:
1086		pcb_sp = &inp->inp_sp->sp_in;
1087		break;
1088	case IPSEC_DIR_OUTBOUND:
1089		pcb_sp = &inp->inp_sp->sp_out;
1090		break;
1091	default:
1092		ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
1093			xpl->sadb_x_policy_dir));
1094		return EINVAL;
1095	}
1096
1097	return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1098}
1099
1100int
1101ipsec4_get_policy(inp, request, len, mp)
1102	struct inpcb *inp;
1103	caddr_t request;
1104	size_t len;
1105	struct mbuf **mp;
1106{
1107	struct sadb_x_policy *xpl;
1108	struct secpolicy *pcb_sp;
1109
1110	/* sanity check. */
1111	if (inp == NULL || request == NULL || mp == NULL)
1112		return EINVAL;
1113	IPSEC_ASSERT(inp->inp_sp != NULL, ("null inp_sp"));
1114	if (len < sizeof(*xpl))
1115		return EINVAL;
1116	xpl = (struct sadb_x_policy *)request;
1117
1118	/* select direction */
1119	switch (xpl->sadb_x_policy_dir) {
1120	case IPSEC_DIR_INBOUND:
1121		pcb_sp = inp->inp_sp->sp_in;
1122		break;
1123	case IPSEC_DIR_OUTBOUND:
1124		pcb_sp = inp->inp_sp->sp_out;
1125		break;
1126	default:
1127		ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
1128			xpl->sadb_x_policy_dir));
1129		return EINVAL;
1130	}
1131
1132	return ipsec_get_policy(pcb_sp, mp);
1133}
1134
1135/* delete policy in PCB */
1136int
1137ipsec4_delete_pcbpolicy(inp)
1138	struct inpcb *inp;
1139{
1140	IPSEC_ASSERT(inp != NULL, ("null inp"));
1141
1142	if (inp->inp_sp == NULL)
1143		return 0;
1144
1145	if (inp->inp_sp->sp_in != NULL)
1146		KEY_FREESP(&inp->inp_sp->sp_in);
1147
1148	if (inp->inp_sp->sp_out != NULL)
1149		KEY_FREESP(&inp->inp_sp->sp_out);
1150
1151	ipsec_delpcbpolicy(inp->inp_sp);
1152	inp->inp_sp = NULL;
1153
1154	return 0;
1155}
1156
1157#ifdef INET6
1158int
1159ipsec6_set_policy(in6p, optname, request, len, priv)
1160	struct in6pcb *in6p;
1161	int optname;
1162	caddr_t request;
1163	size_t len;
1164	int priv;
1165{
1166	struct sadb_x_policy *xpl;
1167	struct secpolicy **pcb_sp;
1168
1169	/* sanity check. */
1170	if (in6p == NULL || request == NULL)
1171		return EINVAL;
1172	if (len < sizeof(*xpl))
1173		return EINVAL;
1174	xpl = (struct sadb_x_policy *)request;
1175
1176	/* select direction */
1177	switch (xpl->sadb_x_policy_dir) {
1178	case IPSEC_DIR_INBOUND:
1179		pcb_sp = &in6p->in6p_sp->sp_in;
1180		break;
1181	case IPSEC_DIR_OUTBOUND:
1182		pcb_sp = &in6p->in6p_sp->sp_out;
1183		break;
1184	default:
1185		ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
1186			xpl->sadb_x_policy_dir));
1187		return EINVAL;
1188	}
1189
1190	return ipsec_set_policy(pcb_sp, optname, request, len, priv);
1191}
1192
1193int
1194ipsec6_get_policy(in6p, request, len, mp)
1195	struct in6pcb *in6p;
1196	caddr_t request;
1197	size_t len;
1198	struct mbuf **mp;
1199{
1200	struct sadb_x_policy *xpl;
1201	struct secpolicy *pcb_sp;
1202
1203	/* sanity check. */
1204	if (in6p == NULL || request == NULL || mp == NULL)
1205		return EINVAL;
1206	IPSEC_ASSERT(in6p->in6p_sp != NULL, ("null in6p_sp"));
1207	if (len < sizeof(*xpl))
1208		return EINVAL;
1209	xpl = (struct sadb_x_policy *)request;
1210
1211	/* select direction */
1212	switch (xpl->sadb_x_policy_dir) {
1213	case IPSEC_DIR_INBOUND:
1214		pcb_sp = in6p->in6p_sp->sp_in;
1215		break;
1216	case IPSEC_DIR_OUTBOUND:
1217		pcb_sp = in6p->in6p_sp->sp_out;
1218		break;
1219	default:
1220		ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__,
1221			xpl->sadb_x_policy_dir));
1222		return EINVAL;
1223	}
1224
1225	return ipsec_get_policy(pcb_sp, mp);
1226}
1227
1228int
1229ipsec6_delete_pcbpolicy(in6p)
1230	struct in6pcb *in6p;
1231{
1232	IPSEC_ASSERT(in6p != NULL, ("null in6p"));
1233
1234	if (in6p->in6p_sp == NULL)
1235		return 0;
1236
1237	if (in6p->in6p_sp->sp_in != NULL)
1238		KEY_FREESP(&in6p->in6p_sp->sp_in);
1239
1240	if (in6p->in6p_sp->sp_out != NULL)
1241		KEY_FREESP(&in6p->in6p_sp->sp_out);
1242
1243	ipsec_delpcbpolicy(in6p->in6p_sp);
1244	in6p->in6p_sp = NULL;
1245
1246	return 0;
1247}
1248#endif
1249
1250/*
1251 * return current level.
1252 * Either IPSEC_LEVEL_USE or IPSEC_LEVEL_REQUIRE are always returned.
1253 */
1254u_int
1255ipsec_get_reqlevel(isr)
1256	struct ipsecrequest *isr;
1257{
1258	u_int level = 0;
1259	u_int esp_trans_deflev, esp_net_deflev;
1260	u_int ah_trans_deflev, ah_net_deflev;
1261
1262	IPSEC_ASSERT(isr != NULL && isr->sp != NULL, ("null argument"));
1263	IPSEC_ASSERT(isr->sp->spidx.src.sa.sa_family == isr->sp->spidx.dst.sa.sa_family,
1264		("af family mismatch, src %u, dst %u",
1265		 isr->sp->spidx.src.sa.sa_family,
1266		 isr->sp->spidx.dst.sa.sa_family));
1267
1268/* XXX note that we have ipseclog() expanded here - code sync issue */
1269#define IPSEC_CHECK_DEFAULT(lev) \
1270	(((lev) != IPSEC_LEVEL_USE && (lev) != IPSEC_LEVEL_REQUIRE	      \
1271			&& (lev) != IPSEC_LEVEL_UNIQUE)			      \
1272		? (ipsec_debug						      \
1273			? log(LOG_INFO, "fixed system default level " #lev ":%d->%d\n",\
1274				(lev), IPSEC_LEVEL_REQUIRE)		      \
1275			: 0),						      \
1276			(lev) = IPSEC_LEVEL_REQUIRE,			      \
1277			(lev)						      \
1278		: (lev))
1279
1280	/* set default level */
1281	switch (((struct sockaddr *)&isr->sp->spidx.src)->sa_family) {
1282#ifdef INET
1283	case AF_INET:
1284		esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_trans_deflev);
1285		esp_net_deflev = IPSEC_CHECK_DEFAULT(ip4_esp_net_deflev);
1286		ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_trans_deflev);
1287		ah_net_deflev = IPSEC_CHECK_DEFAULT(ip4_ah_net_deflev);
1288		break;
1289#endif
1290#ifdef INET6
1291	case AF_INET6:
1292		esp_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_trans_deflev);
1293		esp_net_deflev = IPSEC_CHECK_DEFAULT(ip6_esp_net_deflev);
1294		ah_trans_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_trans_deflev);
1295		ah_net_deflev = IPSEC_CHECK_DEFAULT(ip6_ah_net_deflev);
1296		break;
1297#endif /* INET6 */
1298	default:
1299		panic("%s: unknown af %u",
1300			__func__, isr->sp->spidx.src.sa.sa_family);
1301	}
1302
1303#undef IPSEC_CHECK_DEFAULT
1304
1305	/* set level */
1306	switch (isr->level) {
1307	case IPSEC_LEVEL_DEFAULT:
1308		switch (isr->saidx.proto) {
1309		case IPPROTO_ESP:
1310			if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1311				level = esp_net_deflev;
1312			else
1313				level = esp_trans_deflev;
1314			break;
1315		case IPPROTO_AH:
1316			if (isr->saidx.mode == IPSEC_MODE_TUNNEL)
1317				level = ah_net_deflev;
1318			else
1319				level = ah_trans_deflev;
1320			break;
1321		case IPPROTO_IPCOMP:
1322			/*
1323			 * we don't really care, as IPcomp document says that
1324			 * we shouldn't compress small packets
1325			 */
1326			level = IPSEC_LEVEL_USE;
1327			break;
1328		default:
1329			panic("%s: Illegal protocol defined %u\n", __func__,
1330				isr->saidx.proto);
1331		}
1332		break;
1333
1334	case IPSEC_LEVEL_USE:
1335	case IPSEC_LEVEL_REQUIRE:
1336		level = isr->level;
1337		break;
1338	case IPSEC_LEVEL_UNIQUE:
1339		level = IPSEC_LEVEL_REQUIRE;
1340		break;
1341
1342	default:
1343		panic("%s: Illegal IPsec level %u\n", __func__, isr->level);
1344	}
1345
1346	return level;
1347}
1348
1349/*
1350 * Check security policy requirements against the actual
1351 * packet contents.  Return one if the packet should be
1352 * reject as "invalid"; otherwiser return zero to have the
1353 * packet treated as "valid".
1354 *
1355 * OUT:
1356 *	0: valid
1357 *	1: invalid
1358 */
1359int
1360ipsec_in_reject(struct secpolicy *sp, struct mbuf *m)
1361{
1362	struct ipsecrequest *isr;
1363	int need_auth;
1364
1365	KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1366		printf("%s: using SP\n", __func__); kdebug_secpolicy(sp));
1367
1368	/* check policy */
1369	switch (sp->policy) {
1370	case IPSEC_POLICY_DISCARD:
1371		return 1;
1372	case IPSEC_POLICY_BYPASS:
1373	case IPSEC_POLICY_NONE:
1374		return 0;
1375	}
1376
1377	IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
1378		("invalid policy %u", sp->policy));
1379
1380	/* XXX should compare policy against ipsec header history */
1381
1382	need_auth = 0;
1383	for (isr = sp->req; isr != NULL; isr = isr->next) {
1384		if (ipsec_get_reqlevel(isr) != IPSEC_LEVEL_REQUIRE)
1385			continue;
1386		switch (isr->saidx.proto) {
1387		case IPPROTO_ESP:
1388			if ((m->m_flags & M_DECRYPTED) == 0) {
1389				KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1390				    printf("%s: ESP m_flags:%x\n", __func__,
1391					    m->m_flags));
1392				return 1;
1393			}
1394
1395			if (!need_auth &&
1396			    isr->sav != NULL &&
1397			    isr->sav->tdb_authalgxform != NULL &&
1398			    (m->m_flags & M_AUTHIPDGM) == 0) {
1399				KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1400				    printf("%s: ESP/AH m_flags:%x\n", __func__,
1401					    m->m_flags));
1402				return 1;
1403			}
1404			break;
1405		case IPPROTO_AH:
1406			need_auth = 1;
1407			if ((m->m_flags & M_AUTHIPHDR) == 0) {
1408				KEYDEBUG(KEYDEBUG_IPSEC_DUMP,
1409				    printf("%s: AH m_flags:%x\n", __func__,
1410					    m->m_flags));
1411				return 1;
1412			}
1413			break;
1414		case IPPROTO_IPCOMP:
1415			/*
1416			 * we don't really care, as IPcomp document
1417			 * says that we shouldn't compress small
1418			 * packets, IPComp policy should always be
1419			 * treated as being in "use" level.
1420			 */
1421			break;
1422		}
1423	}
1424	return 0;		/* valid */
1425}
1426
1427/*
1428 * Check AH/ESP integrity.
1429 * This function is called from tcp_input(), udp_input(),
1430 * and {ah,esp}4_input for tunnel mode
1431 */
1432int
1433ipsec4_in_reject(m, inp)
1434	struct mbuf *m;
1435	struct inpcb *inp;
1436{
1437	struct secpolicy *sp;
1438	int error;
1439	int result;
1440
1441	IPSEC_ASSERT(m != NULL, ("null mbuf"));
1442
1443	/* get SP for this packet.
1444	 * When we are called from ip_forward(), we call
1445	 * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
1446	 */
1447	if (inp == NULL)
1448		sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
1449	else
1450		sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error);
1451
1452	if (sp != NULL) {
1453		result = ipsec_in_reject(sp, m);
1454		if (result)
1455			newipsecstat.ips_in_polvio++;
1456		KEY_FREESP(&sp);
1457	} else {
1458		result = 0;	/* XXX should be panic ?
1459				 * -> No, there may be error. */
1460	}
1461	return result;
1462}
1463
1464#ifdef INET6
1465/*
1466 * Check AH/ESP integrity.
1467 * This function is called from tcp6_input(), udp6_input(),
1468 * and {ah,esp}6_input for tunnel mode
1469 */
1470int
1471ipsec6_in_reject(m, inp)
1472	struct mbuf *m;
1473	struct inpcb *inp;
1474{
1475	struct secpolicy *sp = NULL;
1476	int error;
1477	int result;
1478
1479	/* sanity check */
1480	if (m == NULL)
1481		return 0;	/* XXX should be panic ? */
1482
1483	/* get SP for this packet.
1484	 * When we are called from ip_forward(), we call
1485	 * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
1486	 */
1487	if (inp == NULL)
1488		sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, IP_FORWARDING, &error);
1489	else
1490		sp = ipsec_getpolicybysock(m, IPSEC_DIR_INBOUND, inp, &error);
1491
1492	if (sp != NULL) {
1493		result = ipsec_in_reject(sp, m);
1494		if (result)
1495			newipsecstat.ips_in_polvio++;
1496		KEY_FREESP(&sp);
1497	} else {
1498		result = 0;
1499	}
1500	return result;
1501}
1502#endif
1503
1504/*
1505 * compute the byte size to be occupied by IPsec header.
1506 * in case it is tunneled, it includes the size of outer IP header.
1507 * NOTE: SP passed is free in this function.
1508 */
1509static size_t
1510ipsec_hdrsiz(struct secpolicy *sp)
1511{
1512	struct ipsecrequest *isr;
1513	size_t siz;
1514
1515	KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1516		printf("%s: using SP\n", __func__); kdebug_secpolicy(sp));
1517
1518	switch (sp->policy) {
1519	case IPSEC_POLICY_DISCARD:
1520	case IPSEC_POLICY_BYPASS:
1521	case IPSEC_POLICY_NONE:
1522		return 0;
1523	}
1524
1525	IPSEC_ASSERT(sp->policy == IPSEC_POLICY_IPSEC,
1526		("invalid policy %u", sp->policy));
1527
1528	siz = 0;
1529	for (isr = sp->req; isr != NULL; isr = isr->next) {
1530		size_t clen = 0;
1531
1532		switch (isr->saidx.proto) {
1533		case IPPROTO_ESP:
1534			clen = esp_hdrsiz(isr->sav);
1535			break;
1536		case IPPROTO_AH:
1537			clen = ah_hdrsiz(isr->sav);
1538			break;
1539		case IPPROTO_IPCOMP:
1540			clen = sizeof(struct ipcomp);
1541			break;
1542		}
1543
1544		if (isr->saidx.mode == IPSEC_MODE_TUNNEL) {
1545			switch (isr->saidx.dst.sa.sa_family) {
1546			case AF_INET:
1547				clen += sizeof(struct ip);
1548				break;
1549#ifdef INET6
1550			case AF_INET6:
1551				clen += sizeof(struct ip6_hdr);
1552				break;
1553#endif
1554			default:
1555				ipseclog((LOG_ERR, "%s: unknown AF %d in "
1556				    "IPsec tunnel SA\n", __func__,
1557				    ((struct sockaddr *)&isr->saidx.dst)->sa_family));
1558				break;
1559			}
1560		}
1561		siz += clen;
1562	}
1563
1564	return siz;
1565}
1566
1567/* This function is called from ip_forward() and ipsec4_hdrsize_tcp(). */
1568size_t
1569ipsec4_hdrsiz(m, dir, inp)
1570	struct mbuf *m;
1571	u_int dir;
1572	struct inpcb *inp;
1573{
1574	struct secpolicy *sp;
1575	int error;
1576	size_t size;
1577
1578	IPSEC_ASSERT(m != NULL, ("null mbuf"));
1579
1580	/* get SP for this packet.
1581	 * When we are called from ip_forward(), we call
1582	 * ipsec_getpolicybyaddr() with IP_FORWARDING flag.
1583	 */
1584	if (inp == NULL)
1585		sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
1586	else
1587		sp = ipsec_getpolicybysock(m, dir, inp, &error);
1588
1589	if (sp != NULL) {
1590		size = ipsec_hdrsiz(sp);
1591		KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1592			printf("%s: size:%lu.\n", __func__,
1593				(unsigned long)size));
1594
1595		KEY_FREESP(&sp);
1596	} else {
1597		size = 0;	/* XXX should be panic ? */
1598	}
1599	return size;
1600}
1601
1602#ifdef INET6
1603/* This function is called from ipsec6_hdrsize_tcp(),
1604 * and maybe from ip6_forward.()
1605 */
1606size_t
1607ipsec6_hdrsiz(m, dir, in6p)
1608	struct mbuf *m;
1609	u_int dir;
1610	struct in6pcb *in6p;
1611{
1612	struct secpolicy *sp;
1613	int error;
1614	size_t size;
1615
1616	IPSEC_ASSERT(m != NULL, ("null mbuf"));
1617	IPSEC_ASSERT(in6p == NULL || in6p->in6p_socket != NULL,
1618		("socket w/o inpcb"));
1619
1620	/* get SP for this packet */
1621	/* XXX Is it right to call with IP_FORWARDING. */
1622	if (in6p == NULL)
1623		sp = ipsec_getpolicybyaddr(m, dir, IP_FORWARDING, &error);
1624	else
1625		sp = ipsec_getpolicybysock(m, dir, in6p, &error);
1626
1627	if (sp == NULL)
1628		return 0;
1629	size = ipsec_hdrsiz(sp);
1630	KEYDEBUG(KEYDEBUG_IPSEC_DATA,
1631		printf("%s: size:%lu.\n", __func__, (unsigned long)size));
1632	KEY_FREESP(&sp);
1633
1634	return size;
1635}
1636#endif /*INET6*/
1637
1638/*
1639 * Check the variable replay window.
1640 * ipsec_chkreplay() performs replay check before ICV verification.
1641 * ipsec_updatereplay() updates replay bitmap.  This must be called after
1642 * ICV verification (it also performs replay check, which is usually done
1643 * beforehand).
1644 * 0 (zero) is returned if packet disallowed, 1 if packet permitted.
1645 *
1646 * based on RFC 2401.
1647 */
1648int
1649ipsec_chkreplay(seq, sav)
1650	u_int32_t seq;
1651	struct secasvar *sav;
1652{
1653	const struct secreplay *replay;
1654	u_int32_t diff;
1655	int fr;
1656	u_int32_t wsizeb;	/* constant: bits of window size */
1657	int frlast;		/* constant: last frame */
1658
1659	IPSEC_SPLASSERT_SOFTNET(__func__);
1660
1661	IPSEC_ASSERT(sav != NULL, ("Null SA"));
1662	IPSEC_ASSERT(sav->replay != NULL, ("Null replay state"));
1663
1664	replay = sav->replay;
1665
1666	if (replay->wsize == 0)
1667		return 1;	/* no need to check replay. */
1668
1669	/* constant */
1670	frlast = replay->wsize - 1;
1671	wsizeb = replay->wsize << 3;
1672
1673	/* sequence number of 0 is invalid */
1674	if (seq == 0)
1675		return 0;
1676
1677	/* first time is always okay */
1678	if (replay->count == 0)
1679		return 1;
1680
1681	if (seq > replay->lastseq) {
1682		/* larger sequences are okay */
1683		return 1;
1684	} else {
1685		/* seq is equal or less than lastseq. */
1686		diff = replay->lastseq - seq;
1687
1688		/* over range to check, i.e. too old or wrapped */
1689		if (diff >= wsizeb)
1690			return 0;
1691
1692		fr = frlast - diff / 8;
1693
1694		/* this packet already seen ? */
1695		if ((replay->bitmap)[fr] & (1 << (diff % 8)))
1696			return 0;
1697
1698		/* out of order but good */
1699		return 1;
1700	}
1701}
1702
1703/*
1704 * check replay counter whether to update or not.
1705 * OUT:	0:	OK
1706 *	1:	NG
1707 */
1708int
1709ipsec_updatereplay(seq, sav)
1710	u_int32_t seq;
1711	struct secasvar *sav;
1712{
1713	struct secreplay *replay;
1714	u_int32_t diff;
1715	int fr;
1716	u_int32_t wsizeb;	/* constant: bits of window size */
1717	int frlast;		/* constant: last frame */
1718
1719	IPSEC_SPLASSERT_SOFTNET(__func__);
1720
1721	IPSEC_ASSERT(sav != NULL, ("Null SA"));
1722	IPSEC_ASSERT(sav->replay != NULL, ("Null replay state"));
1723
1724	replay = sav->replay;
1725
1726	if (replay->wsize == 0)
1727		goto ok;	/* no need to check replay. */
1728
1729	/* constant */
1730	frlast = replay->wsize - 1;
1731	wsizeb = replay->wsize << 3;
1732
1733	/* sequence number of 0 is invalid */
1734	if (seq == 0)
1735		return 1;
1736
1737	/* first time */
1738	if (replay->count == 0) {
1739		replay->lastseq = seq;
1740		bzero(replay->bitmap, replay->wsize);
1741		(replay->bitmap)[frlast] = 1;
1742		goto ok;
1743	}
1744
1745	if (seq > replay->lastseq) {
1746		/* seq is larger than lastseq. */
1747		diff = seq - replay->lastseq;
1748
1749		/* new larger sequence number */
1750		if (diff < wsizeb) {
1751			/* In window */
1752			/* set bit for this packet */
1753			vshiftl(replay->bitmap, diff, replay->wsize);
1754			(replay->bitmap)[frlast] |= 1;
1755		} else {
1756			/* this packet has a "way larger" */
1757			bzero(replay->bitmap, replay->wsize);
1758			(replay->bitmap)[frlast] = 1;
1759		}
1760		replay->lastseq = seq;
1761
1762		/* larger is good */
1763	} else {
1764		/* seq is equal or less than lastseq. */
1765		diff = replay->lastseq - seq;
1766
1767		/* over range to check, i.e. too old or wrapped */
1768		if (diff >= wsizeb)
1769			return 1;
1770
1771		fr = frlast - diff / 8;
1772
1773		/* this packet already seen ? */
1774		if ((replay->bitmap)[fr] & (1 << (diff % 8)))
1775			return 1;
1776
1777		/* mark as seen */
1778		(replay->bitmap)[fr] |= (1 << (diff % 8));
1779
1780		/* out of order but good */
1781	}
1782
1783ok:
1784	if (replay->count == ~0) {
1785
1786		/* set overflow flag */
1787		replay->overflow++;
1788
1789		/* don't increment, no more packets accepted */
1790		if ((sav->flags & SADB_X_EXT_CYCSEQ) == 0)
1791			return 1;
1792
1793		ipseclog((LOG_WARNING, "%s: replay counter made %d cycle. %s\n",
1794		    __func__, replay->overflow, ipsec_logsastr(sav)));
1795	}
1796
1797	replay->count++;
1798
1799	return 0;
1800}
1801
1802/*
1803 * shift variable length buffer to left.
1804 * IN:	bitmap: pointer to the buffer
1805 * 	nbit:	the number of to shift.
1806 *	wsize:	buffer size (bytes).
1807 */
1808static void
1809vshiftl(bitmap, nbit, wsize)
1810	unsigned char *bitmap;
1811	int nbit, wsize;
1812{
1813	int s, j, i;
1814	unsigned char over;
1815
1816	for (j = 0; j < nbit; j += 8) {
1817		s = (nbit - j < 8) ? (nbit - j): 8;
1818		bitmap[0] <<= s;
1819		for (i = 1; i < wsize; i++) {
1820			over = (bitmap[i] >> (8 - s));
1821			bitmap[i] <<= s;
1822			bitmap[i-1] |= over;
1823		}
1824	}
1825
1826	return;
1827}
1828
1829/* Return a printable string for the IPv4 address. */
1830static char *
1831inet_ntoa4(struct in_addr ina)
1832{
1833	static char buf[4][4 * sizeof "123" + 4];
1834	unsigned char *ucp = (unsigned char *) &ina;
1835	static int i = 3;
1836
1837	/* XXX-BZ returns static buffer. */
1838	i = (i + 1) % 4;
1839	sprintf(buf[i], "%d.%d.%d.%d", ucp[0] & 0xff, ucp[1] & 0xff,
1840	    ucp[2] & 0xff, ucp[3] & 0xff);
1841	return (buf[i]);
1842}
1843
1844/* Return a printable string for the address. */
1845char *
1846ipsec_address(union sockaddr_union* sa)
1847{
1848#ifdef INET6
1849	char ip6buf[INET6_ADDRSTRLEN];
1850#endif
1851	switch (sa->sa.sa_family) {
1852#ifdef INET
1853	case AF_INET:
1854		return inet_ntoa4(sa->sin.sin_addr);
1855#endif /* INET */
1856
1857#ifdef INET6
1858	case AF_INET6:
1859		return ip6_sprintf(ip6buf, &sa->sin6.sin6_addr);
1860#endif /* INET6 */
1861
1862	default:
1863		return "(unknown address family)";
1864	}
1865}
1866
1867const char *
1868ipsec_logsastr(sav)
1869	struct secasvar *sav;
1870{
1871	static char buf[256];
1872	char *p;
1873	struct secasindex *saidx = &sav->sah->saidx;
1874
1875	IPSEC_ASSERT(saidx->src.sa.sa_family == saidx->dst.sa.sa_family,
1876		("address family mismatch"));
1877
1878	p = buf;
1879	snprintf(buf, sizeof(buf), "SA(SPI=%u ", (u_int32_t)ntohl(sav->spi));
1880	while (p && *p)
1881		p++;
1882	/* NB: only use ipsec_address on one address at a time */
1883	snprintf(p, sizeof (buf) - (p - buf), "src=%s ",
1884		ipsec_address(&saidx->src));
1885	while (p && *p)
1886		p++;
1887	snprintf(p, sizeof (buf) - (p - buf), "dst=%s)",
1888		ipsec_address(&saidx->dst));
1889
1890	return buf;
1891}
1892
1893void
1894ipsec_dumpmbuf(m)
1895	struct mbuf *m;
1896{
1897	int totlen;
1898	int i;
1899	u_char *p;
1900
1901	totlen = 0;
1902	printf("---\n");
1903	while (m) {
1904		p = mtod(m, u_char *);
1905		for (i = 0; i < m->m_len; i++) {
1906			printf("%02x ", p[i]);
1907			totlen++;
1908			if (totlen % 16 == 0)
1909				printf("\n");
1910		}
1911		m = m->m_next;
1912	}
1913	if (totlen % 16 != 0)
1914		printf("\n");
1915	printf("---\n");
1916}
1917
1918static void
1919ipsec_attach(void)
1920{
1921	SECPOLICY_LOCK_INIT(&ip4_def_policy);
1922	ip4_def_policy.refcnt = 1;			/* NB: disallow free */
1923}
1924SYSINIT(ipsec, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, ipsec_attach, NULL)
1925
1926
1927/* XXX this stuff doesn't belong here... */
1928
1929static	struct xformsw* xforms = NULL;
1930
1931/*
1932 * Register a transform; typically at system startup.
1933 */
1934void
1935xform_register(struct xformsw* xsp)
1936{
1937	xsp->xf_next = xforms;
1938	xforms = xsp;
1939}
1940
1941/*
1942 * Initialize transform support in an sav.
1943 */
1944int
1945xform_init(struct secasvar *sav, int xftype)
1946{
1947	struct xformsw *xsp;
1948
1949	if (sav->tdb_xform != NULL)	/* previously initialized */
1950		return 0;
1951	for (xsp = xforms; xsp; xsp = xsp->xf_next)
1952		if (xsp->xf_type == xftype)
1953			return (*xsp->xf_init)(sav, xsp);
1954	return EINVAL;
1955}
1956