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