1f6bdcf8sam/*	$FreeBSD$	*/
2f6bdcf8sam/*	$KAME: ipsec.c,v 1.103 2001/05/24 07:14:18 sakane Exp $	*/
3f6bdcf8sam
4a50ffc2imp/*-
54736ccfpfg * SPDX-License-Identifier: BSD-3-Clause
64736ccfpfg *
7f6bdcf8sam * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
8f6bdcf8sam * All rights reserved.
9f6bdcf8sam *
10f6bdcf8sam * Redistribution and use in source and binary forms, with or without
11f6bdcf8sam * modification, are permitted provided that the following conditions
12f6bdcf8sam * are met:
13f6bdcf8sam * 1. Redistributions of source code must retain the above copyright
14f6bdcf8sam *    notice, this list of conditions and the following disclaimer.
15f6bdcf8sam * 2. Redistributions in binary form must reproduce the above copyright
16f6bdcf8sam *    notice, this list of conditions and the following disclaimer in the
17f6bdcf8sam *    documentation and/or other materials provided with the distribution.
18f6bdcf8sam * 3. Neither the name of the project nor the names of its contributors
19f6bdcf8sam *    may be used to endorse or promote products derived from this software
20f6bdcf8sam *    without specific prior written permission.
21f6bdcf8sam *
22f6bdcf8sam * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
23f6bdcf8sam * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24f6bdcf8sam * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25f6bdcf8sam * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
26f6bdcf8sam * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27f6bdcf8sam * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28f6bdcf8sam * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29f6bdcf8sam * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30f6bdcf8sam * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31f6bdcf8sam * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32f6bdcf8sam * SUCH DAMAGE.
33f6bdcf8sam */
34f6bdcf8sam
35f6bdcf8sam/*
36f6bdcf8sam * IPsec controller part.
37f6bdcf8sam */
38f6bdcf8sam
39f6bdcf8sam#include "opt_inet.h"
40f6bdcf8sam#include "opt_inet6.h"
41f6bdcf8sam#include "opt_ipsec.h"
42f6bdcf8sam
43f6bdcf8sam#include <sys/param.h>
44f6bdcf8sam#include <sys/systm.h>
45f6bdcf8sam#include <sys/malloc.h>
46f6bdcf8sam#include <sys/mbuf.h>
47f6bdcf8sam#include <sys/domain.h>
48f52cf26rwatson#include <sys/priv.h>
49f6bdcf8sam#include <sys/protosw.h>
50f6bdcf8sam#include <sys/socket.h>
51f6bdcf8sam#include <sys/socketvar.h>
52f6bdcf8sam#include <sys/errno.h>
53d81208cae#include <sys/hhook.h>
54f6bdcf8sam#include <sys/time.h>
55f6bdcf8sam#include <sys/kernel.h>
56f6bdcf8sam#include <sys/syslog.h>
57f6bdcf8sam#include <sys/sysctl.h>
58f6bdcf8sam#include <sys/proc.h>
59f6bdcf8sam
60f6bdcf8sam#include <net/if.h>
61d81208cae#include <net/if_enc.h>
62ff6e113glebius#include <net/if_var.h>
6357ca458rwatson#include <net/vnet.h>
64f6bdcf8sam
65f6bdcf8sam#include <netinet/in.h>
66f6bdcf8sam#include <netinet/in_systm.h>
67f6bdcf8sam#include <netinet/ip.h>
68f6bdcf8sam#include <netinet/ip_var.h>
69f6bdcf8sam#include <netinet/in_var.h>
70f6bdcf8sam#include <netinet/udp.h>
71f6bdcf8sam#include <netinet/udp_var.h>
72f6bdcf8sam#include <netinet/tcp.h>
73f6bdcf8sam#include <netinet/udp.h>
74f6bdcf8sam
75f6bdcf8sam#include <netinet/ip6.h>
76f6bdcf8sam#ifdef INET6
77f6bdcf8sam#include <netinet6/ip6_var.h>
78f6bdcf8sam#endif
79f6bdcf8sam#include <netinet/in_pcb.h>
80f6bdcf8sam#ifdef INET6
81f6bdcf8sam#include <netinet/icmp6.h>
82f6bdcf8sam#endif
83f6bdcf8sam
840cd74dbgnn#include <sys/types.h>
85f6bdcf8sam#include <netipsec/ipsec.h>
86f6bdcf8sam#ifdef INET6
87f6bdcf8sam#include <netipsec/ipsec6.h>
88f6bdcf8sam#endif
89f6bdcf8sam#include <netipsec/ah_var.h>
90f6bdcf8sam#include <netipsec/esp_var.h>
91f6bdcf8sam#include <netipsec/ipcomp.h>		/*XXX*/
92f6bdcf8sam#include <netipsec/ipcomp_var.h>
930fb6ad5ae#include <netipsec/ipsec_support.h>
94f6bdcf8sam
95f6bdcf8sam#include <netipsec/key.h>
96f6bdcf8sam#include <netipsec/keydb.h>
97f6bdcf8sam#include <netipsec/key_debug.h>
98f6bdcf8sam
99f6bdcf8sam#include <netipsec/xform.h>
100f6bdcf8sam
101f6bdcf8sam#include <machine/in_cksum.h>
102f6bdcf8sam
10319daed6sam#include <opencrypto/cryptodev.h>
10419daed6sam
10514a7b2cbz/* NB: name changed so netstat doesn't use it. */
106d467a41aeVNET_PCPUSTAT_DEFINE(struct ipsecstat, ipsec4stat);
107d467a41aeVNET_PCPUSTAT_SYSINIT(ipsec4stat);
108d467a41ae
109d467a41ae#ifdef VIMAGE
110d467a41aeVNET_PCPUSTAT_SYSUNINIT(ipsec4stat);
111d467a41ae#endif /* VIMAGE */
112d467a41ae
11357ca458rwatson/* DF bit on encap. 0: clear 1: set 2: copy */
11457ca458rwatsonVNET_DEFINE(int, ip4_ipsec_dfbit) = 0;
11557ca458rwatsonVNET_DEFINE(int, ip4_esp_trans_deflev) = IPSEC_LEVEL_USE;
11657ca458rwatsonVNET_DEFINE(int, ip4_esp_net_deflev) = IPSEC_LEVEL_USE;
11757ca458rwatsonVNET_DEFINE(int, ip4_ah_trans_deflev) = IPSEC_LEVEL_USE;
11857ca458rwatsonVNET_DEFINE(int, ip4_ah_net_deflev) = IPSEC_LEVEL_USE;
11957ca458rwatson/* ECN ignore(-1)/forbidden(0)/allowed(1) */
12057ca458rwatsonVNET_DEFINE(int, ip4_ipsec_ecn) = 0;
12157ca458rwatson
122a6605d2andrewVNET_DEFINE_STATIC(int, ip4_filtertunnel) = 0;
1230fb6ad5ae#define	V_ip4_filtertunnel VNET(ip4_filtertunnel)
124a6605d2andrewVNET_DEFINE_STATIC(int, check_policy_history) = 0;
1250fb6ad5ae#define	V_check_policy_history	VNET(check_policy_history)
126a6605d2andrewVNET_DEFINE_STATIC(struct secpolicy *, def_policy) = NULL;
12784b82e8ae#define	V_def_policy	VNET(def_policy)
1280fb6ad5aestatic int
1290fb6ad5aesysctl_def_policy(SYSCTL_HANDLER_ARGS)
1300fb6ad5ae{
1310fb6ad5ae	int error, value;
1320fb6ad5ae
1330fb6ad5ae	value = V_def_policy->policy;
1340fb6ad5ae	error = sysctl_handle_int(oidp, &value, 0, req);
1350fb6ad5ae	if (error == 0) {
1360fb6ad5ae		if (value != IPSEC_POLICY_DISCARD &&
1370fb6ad5ae		    value != IPSEC_POLICY_NONE)
1380fb6ad5ae			return (EINVAL);
1390fb6ad5ae		V_def_policy->policy = value;
1400fb6ad5ae	}
1410fb6ad5ae	return (error);
1420fb6ad5ae}
1430fb6ad5ae
144f6bdcf8sam/*
145f6bdcf8sam * Crypto support requirements:
146f6bdcf8sam *
147f6bdcf8sam *  1	require hardware support
148f6bdcf8sam * -1	require software support
149f6bdcf8sam *  0	take anything
150f6bdcf8sam */
15157ca458rwatsonVNET_DEFINE(int, crypto_support) = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
152fbc9da5fabient
153fbc9da5fabient/*
154fbc9da5fabient * Use asynchronous mode to parallelize crypto jobs:
155fbc9da5fabient *
156fbc9da5fabient *  0 - disabled
157fbc9da5fabient *  1 - enabled
158fbc9da5fabient */
159fbc9da5fabientVNET_DEFINE(int, async_crypto) = 0;
160fbc9da5fabient
1610fb6ad5ae/*
1620fb6ad5ae * TCP/UDP checksum handling policy for transport mode NAT-T (RFC3948)
1630fb6ad5ae *
1640fb6ad5ae * 0 - auto: incrementally recompute, when checksum delta is known;
1650fb6ad5ae *     if checksum delta isn't known, reset checksum to zero for UDP,
1660fb6ad5ae *     and mark csum_flags as valid for TCP.
1670fb6ad5ae * 1 - fully recompute TCP/UDP checksum.
1680fb6ad5ae */
1690fb6ad5aeVNET_DEFINE(int, natt_cksum_policy) = 0;
170f6bdcf8sam
171d198c87bzFEATURE(ipsec, "Internet Protocol Security (IPsec)");
172d198c87bzFEATURE(ipsec_natt, "UDP Encapsulation of IPsec ESP Packets ('NAT-T')");
173d198c87bz
174f6bdcf8samSYSCTL_DECL(_net_inet_ipsec);
175f6bdcf8sam
176f6bdcf8sam/* net.inet.ipsec */
1770fb6ad5aeSYSCTL_PROC(_net_inet_ipsec, IPSECCTL_DEF_POLICY, def_policy,
178ad355b0kaktus    CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
179ad355b0kaktus    0, 0, sysctl_def_policy, "I",
180ad355b0kaktus    "IPsec default policy.");
18199f4ec5glebiusSYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
18299f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_esp_trans_deflev), 0,
1838797d4czec	"Default ESP transport mode level");
18499f4ec5glebiusSYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
18599f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_esp_net_deflev), 0,
1868797d4czec	"Default ESP tunnel mode level.");
18799f4ec5glebiusSYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
18899f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ah_trans_deflev), 0,
1898797d4czec	"AH transfer mode default level.");
19099f4ec5glebiusSYSCTL_INT(_net_inet_ipsec, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
19199f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ah_net_deflev), 0,
1928797d4czec	"AH tunnel mode default level.");
19399f4ec5glebiusSYSCTL_INT(_net_inet_ipsec, IPSECCTL_AH_CLEARTOS, ah_cleartos,
19499f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ah_cleartos), 0,
1950fb6ad5ae	"If set, clear type-of-service field when doing AH computation.");
19699f4ec5glebiusSYSCTL_INT(_net_inet_ipsec, IPSECCTL_DFBIT, dfbit,
19799f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ipsec_dfbit), 0,
1988797d4czec	"Do not fragment bit on encap.");
19999f4ec5glebiusSYSCTL_INT(_net_inet_ipsec, IPSECCTL_ECN, ecn,
20099f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_ipsec_ecn), 0,
2018797d4czec	"Explicit Congestion Notification handling.");
20299f4ec5glebiusSYSCTL_INT(_net_inet_ipsec, OID_AUTO, crypto_support,
20399f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(crypto_support), 0,
2048797d4czec	"Crypto driver selection.");
205fbc9da5fabientSYSCTL_INT(_net_inet_ipsec, OID_AUTO, async_crypto,
206fbc9da5fabient	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(async_crypto), 0,
207fbc9da5fabient	"Use asynchronous mode to parallelize crypto jobs.");
2080fb6ad5aeSYSCTL_INT(_net_inet_ipsec, OID_AUTO, check_policy_history,
2090fb6ad5ae	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(check_policy_history), 0,
2100fb6ad5ae	"Use strict check of inbound packets to security policy compliance.");
2110fb6ad5aeSYSCTL_INT(_net_inet_ipsec, OID_AUTO, natt_cksum_policy,
2120fb6ad5ae	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(natt_cksum_policy), 0,
2130fb6ad5ae	"Method to fix TCP/UDP checksum for transport mode IPsec after NAT.");
2140fb6ad5aeSYSCTL_INT(_net_inet_ipsec, OID_AUTO, filtertunnel,
2150fb6ad5ae	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip4_filtertunnel), 0,
2160fb6ad5ae	"If set, filter packets from an IPsec tunnel.");
217d467a41aeSYSCTL_VNET_PCPUSTAT(_net_inet_ipsec, OID_AUTO, ipsecstats, struct ipsecstat,
218d467a41ae    ipsec4stat, "IPsec IPv4 statistics.");
219f6bdcf8sam
22098fc993pjd#ifdef REGRESSION
2210501edbpjd/*
2220501edbpjd * When set to 1, IPsec will send packets with the same sequence number.
2230501edbpjd * This allows to verify if the other side has proper replay attacks detection.
2240501edbpjd */
22557ca458rwatsonVNET_DEFINE(int, ipsec_replay) = 0;
22699f4ec5glebiusSYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_replay,
22799f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ipsec_replay), 0,
22857ca458rwatson	"Emulate replay attack");
2290501edbpjd/*
2300501edbpjd * When set 1, IPsec will send packets with corrupted HMAC.
2310501edbpjd * This allows to verify if the other side properly detects modified packets.
2320501edbpjd */
23357ca458rwatsonVNET_DEFINE(int, ipsec_integrity) = 0;
23499f4ec5glebiusSYSCTL_INT(_net_inet_ipsec, OID_AUTO, test_integrity,
23599f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ipsec_integrity), 0,
23657ca458rwatson	"Emulate man-in-the-middle attack");
23798fc993pjd#endif
2380501edbpjd
2390cd74dbgnn#ifdef INET6
240d467a41aeVNET_PCPUSTAT_DEFINE(struct ipsecstat, ipsec6stat);
241d467a41aeVNET_PCPUSTAT_SYSINIT(ipsec6stat);
242d467a41ae
243d467a41ae#ifdef VIMAGE
244d467a41aeVNET_PCPUSTAT_SYSUNINIT(ipsec6stat);
245d467a41ae#endif /* VIMAGE */
246d467a41ae
24757ca458rwatsonVNET_DEFINE(int, ip6_esp_trans_deflev) = IPSEC_LEVEL_USE;
24857ca458rwatsonVNET_DEFINE(int, ip6_esp_net_deflev) = IPSEC_LEVEL_USE;
24957ca458rwatsonVNET_DEFINE(int, ip6_ah_trans_deflev) = IPSEC_LEVEL_USE;
25057ca458rwatsonVNET_DEFINE(int, ip6_ah_net_deflev) = IPSEC_LEVEL_USE;
25157ca458rwatsonVNET_DEFINE(int, ip6_ipsec_ecn) = 0;	/* ECN ignore(-1)/forbidden(0)/allowed(1) */
252f6bdcf8sam
253a6605d2andrewVNET_DEFINE_STATIC(int, ip6_filtertunnel) = 0;
2540fb6ad5ae#define	V_ip6_filtertunnel	VNET(ip6_filtertunnel)
2550fb6ad5ae
256f6bdcf8samSYSCTL_DECL(_net_inet6_ipsec6);
257f6bdcf8sam
258f6bdcf8sam/* net.inet6.ipsec6 */
2590fb6ad5aeSYSCTL_PROC(_net_inet6_ipsec6, IPSECCTL_DEF_POLICY, def_policy,
260ad355b0kaktus    CTLTYPE_INT | CTLFLAG_VNET | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
261ad355b0kaktus    0, 0, sysctl_def_policy, "I",
262ad355b0kaktus    "IPsec default policy.");
26399f4ec5glebiusSYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_TRANSLEV, esp_trans_deflev,
26499f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_esp_trans_deflev), 0,
2658797d4czec	"Default ESP transport mode level.");
26699f4ec5glebiusSYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_ESP_NETLEV, esp_net_deflev,
26799f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_esp_net_deflev), 0,
2688797d4czec	"Default ESP tunnel mode level.");
26999f4ec5glebiusSYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_TRANSLEV, ah_trans_deflev,
27099f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_ah_trans_deflev), 0,
2718797d4czec	"AH transfer mode default level.");
27299f4ec5glebiusSYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_DEF_AH_NETLEV, ah_net_deflev,
27399f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_ah_net_deflev), 0,
2748797d4czec	"AH tunnel mode default level.");
27599f4ec5glebiusSYSCTL_INT(_net_inet6_ipsec6, IPSECCTL_ECN, ecn,
27699f4ec5glebius	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_ipsec_ecn), 0,
2778797d4czec	"Explicit Congestion Notification handling.");
2780fb6ad5aeSYSCTL_INT(_net_inet6_ipsec6, OID_AUTO, filtertunnel,
2790fb6ad5ae	CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_filtertunnel),  0,
2800fb6ad5ae	"If set, filter packets from an IPsec tunnel.");
281d467a41aeSYSCTL_VNET_PCPUSTAT(_net_inet6_ipsec6, IPSECCTL_STATS, ipsecstats,
282d467a41ae    struct ipsecstat, ipsec6stat, "IPsec IPv6 statistics.");
283f6bdcf8sam#endif /* INET6 */
284f6bdcf8sam
2850fb6ad5aestatic int ipsec_in_reject(struct secpolicy *, struct inpcb *,
2860fb6ad5ae    const struct mbuf *);
2870fb6ad5ae
2880fb6ad5ae#ifdef INET
2890fb6ad5aestatic void ipsec4_get_ulp(const struct mbuf *, struct secpolicyindex *, int);
2900fb6ad5aestatic void ipsec4_setspidx_ipaddr(const struct mbuf *,
2910fb6ad5ae    struct secpolicyindex *);
2920fb6ad5ae#endif
293f6bdcf8sam#ifdef INET6
29440afb9faestatic void ipsec6_get_ulp(const struct mbuf *m, struct secpolicyindex *, int);
2950fb6ad5aestatic void ipsec6_setspidx_ipaddr(const struct mbuf *,
2960fb6ad5ae    struct secpolicyindex *);
297f6bdcf8sam#endif
298