1*2fd9c36dSozaki-r /* $NetBSD: ipsec.h,v 1.93 2022/10/28 05:23:09 ozaki-r Exp $ */
2e2c8a664Smaxv /* $FreeBSD: ipsec.h,v 1.2.4.2 2004/02/14 22:23:23 bms Exp $ */
374029031Sjonathan /* $KAME: ipsec.h,v 1.53 2001/11/20 08:32:38 itojun Exp $ */
474029031Sjonathan
574029031Sjonathan /*
674029031Sjonathan * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
774029031Sjonathan * All rights reserved.
874029031Sjonathan *
974029031Sjonathan * Redistribution and use in source and binary forms, with or without
1074029031Sjonathan * modification, are permitted provided that the following conditions
1174029031Sjonathan * are met:
1274029031Sjonathan * 1. Redistributions of source code must retain the above copyright
1374029031Sjonathan * notice, this list of conditions and the following disclaimer.
1474029031Sjonathan * 2. Redistributions in binary form must reproduce the above copyright
1574029031Sjonathan * notice, this list of conditions and the following disclaimer in the
1674029031Sjonathan * documentation and/or other materials provided with the distribution.
1774029031Sjonathan * 3. Neither the name of the project nor the names of its contributors
1874029031Sjonathan * may be used to endorse or promote products derived from this software
1974029031Sjonathan * without specific prior written permission.
2074029031Sjonathan *
2174029031Sjonathan * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
2274029031Sjonathan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2374029031Sjonathan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2474029031Sjonathan * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2574029031Sjonathan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2674029031Sjonathan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2774029031Sjonathan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2874029031Sjonathan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2974029031Sjonathan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3074029031Sjonathan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3174029031Sjonathan * SUCH DAMAGE.
3274029031Sjonathan */
3374029031Sjonathan
3474029031Sjonathan #ifndef _NETIPSEC_IPSEC_H_
3574029031Sjonathan #define _NETIPSEC_IPSEC_H_
3674029031Sjonathan
370efea177Sad #if defined(_KERNEL_OPT)
3874029031Sjonathan #include "opt_inet.h"
3974029031Sjonathan #include "opt_ipsec.h"
4074029031Sjonathan #endif
4174029031Sjonathan
4274029031Sjonathan #include <net/pfkeyv2.h>
4374029031Sjonathan
4474029031Sjonathan #ifdef _KERNEL
454ce45a79Sozaki-r #include <sys/socketvar.h>
460c084e85Sozaki-r #include <sys/localcount.h>
4774029031Sjonathan
480e390eeeSozaki-r #include <netinet/in_pcb.h>
4947a381e1Sdrochner #include <netipsec/keydb.h>
503712f81cSdrochner
5174029031Sjonathan /*
5274029031Sjonathan * Security Policy Index
5374029031Sjonathan * Ensure that both address families in the "src" and "dst" are same.
5474029031Sjonathan * When the value of the ul_proto is ICMPv6, the port field in "src"
5574029031Sjonathan * specifies ICMPv6 type, and the port field in "dst" specifies ICMPv6 code.
5674029031Sjonathan */
5774029031Sjonathan struct secpolicyindex {
5874029031Sjonathan u_int8_t dir; /* direction of packet flow, see blow */
5974029031Sjonathan union sockaddr_union src; /* IP src address for SP */
6074029031Sjonathan union sockaddr_union dst; /* IP dst address for SP */
6174029031Sjonathan u_int8_t prefs; /* prefix length in bits for src */
6274029031Sjonathan u_int8_t prefd; /* prefix length in bits for dst */
6374029031Sjonathan u_int16_t ul_proto; /* upper layer Protocol */
6474029031Sjonathan };
6574029031Sjonathan
6674029031Sjonathan /* Security Policy Data Base */
6774029031Sjonathan struct secpolicy {
6867baf592Sozaki-r struct pslist_entry pslist_entry;
6974029031Sjonathan
700c084e85Sozaki-r struct localcount localcount; /* reference count */
7174029031Sjonathan struct secpolicyindex spidx; /* selector */
7274029031Sjonathan u_int32_t id; /* It's unique number on the system. */
7374029031Sjonathan u_int state; /* 0: dead, others: alive */
7474029031Sjonathan #define IPSEC_SPSTATE_DEAD 0
7574029031Sjonathan #define IPSEC_SPSTATE_ALIVE 1
7674029031Sjonathan
774ab3af3eSknakahara u_int origin; /* who generate this SP. */
784ab3af3eSknakahara #define IPSEC_SPORIGIN_USER 0
794ab3af3eSknakahara #define IPSEC_SPORIGIN_KERNEL 1
804ab3af3eSknakahara
8174029031Sjonathan u_int policy; /* DISCARD, NONE or IPSEC, see keyv2.h */
8274029031Sjonathan struct ipsecrequest *req;
8374029031Sjonathan /* pointer to the ipsec request tree, */
8474029031Sjonathan /* if policy == IPSEC else this value == NULL.*/
8574029031Sjonathan
8674029031Sjonathan /*
8774029031Sjonathan * lifetime handler.
8874029031Sjonathan * the policy can be used without limitiation if both lifetime and
8974029031Sjonathan * validtime are zero.
9074029031Sjonathan * "lifetime" is passed by sadb_lifetime.sadb_lifetime_addtime.
9174029031Sjonathan * "validtime" is passed by sadb_lifetime.sadb_lifetime_usetime.
9274029031Sjonathan */
9306d326dfSdrochner time_t created; /* time created the policy */
9406d326dfSdrochner time_t lastused; /* updated every when kernel sends a packet */
9506d326dfSdrochner time_t lifetime; /* duration of the lifetime of this policy */
9606d326dfSdrochner time_t validtime; /* duration this policy is valid without use */
9774029031Sjonathan };
9874029031Sjonathan
9974029031Sjonathan /* Request for IPsec */
10074029031Sjonathan struct ipsecrequest {
10174029031Sjonathan struct ipsecrequest *next;
10274029031Sjonathan /* pointer to next structure */
10374029031Sjonathan /* If NULL, it means the end of chain. */
10474029031Sjonathan struct secasindex saidx;/* hint for search proper SA */
10574029031Sjonathan /* if __ss_len == 0 then no address specified.*/
10674029031Sjonathan u_int level; /* IPsec level defined below. */
10774029031Sjonathan
10874029031Sjonathan struct secpolicy *sp; /* back pointer to SP */
10974029031Sjonathan };
11074029031Sjonathan
11174029031Sjonathan /* security policy in PCB */
11274029031Sjonathan struct inpcbpolicy {
11374029031Sjonathan struct secpolicy *sp_in;
11474029031Sjonathan struct secpolicy *sp_out;
11574029031Sjonathan int priv; /* privileged socket ? */
116ce5ecc33Sthorpej
117ce5ecc33Sthorpej /* cached policy */
118ce5ecc33Sthorpej struct {
119ce5ecc33Sthorpej struct secpolicy *cachesp;
120ce5ecc33Sthorpej struct secpolicyindex cacheidx;
121ce5ecc33Sthorpej int cachehint; /* processing requirement hint: */
122a11fe343Sozaki-r #define IPSEC_PCBHINT_UNKNOWN 0 /* Unknown */
123ce5ecc33Sthorpej #define IPSEC_PCBHINT_YES 1 /* IPsec processing is required */
124ce5ecc33Sthorpej #define IPSEC_PCBHINT_NO 2 /* IPsec processing not required */
125ce5ecc33Sthorpej u_int cachegen; /* spdgen when cache filled */
126ce5ecc33Sthorpej } sp_cache[3]; /* XXX 3 == IPSEC_DIR_MAX */
127ce5ecc33Sthorpej int sp_cacheflags;
128ce5ecc33Sthorpej #define IPSEC_PCBSP_CONNECTED 1
1290e390eeeSozaki-r struct inpcb *sp_inp; /* back pointer */
13074029031Sjonathan };
13174029031Sjonathan
1324ce45a79Sozaki-r extern u_int ipsec_spdgen;
1334ce45a79Sozaki-r
13487fd18f8Schristos static __inline bool
ipsec_pcb_skip_ipsec(struct inpcbpolicy * pcbsp,int dir)1354ce45a79Sozaki-r ipsec_pcb_skip_ipsec(struct inpcbpolicy *pcbsp, int dir)
1364ce45a79Sozaki-r {
1374ce45a79Sozaki-r
1380e390eeeSozaki-r KASSERT(inp_locked(pcbsp->sp_inp));
1394ce45a79Sozaki-r
1404ce45a79Sozaki-r return pcbsp->sp_cache[(dir)].cachehint == IPSEC_PCBHINT_NO &&
1414ce45a79Sozaki-r pcbsp->sp_cache[(dir)].cachegen == ipsec_spdgen;
1424ce45a79Sozaki-r }
143ce5ecc33Sthorpej
14474029031Sjonathan /* SP acquiring list table. */
14574029031Sjonathan struct secspacq {
14674029031Sjonathan LIST_ENTRY(secspacq) chain;
14774029031Sjonathan
14874029031Sjonathan struct secpolicyindex spidx;
14974029031Sjonathan
15006d326dfSdrochner time_t created; /* for lifetime */
15174029031Sjonathan int count; /* for lifetime */
15274029031Sjonathan /* XXX: here is mbuf place holder to be sent ? */
15374029031Sjonathan };
15474029031Sjonathan #endif /* _KERNEL */
15574029031Sjonathan
156dd8c81f5Sryo /* buffer size for formatted output of ipsec address (addr + '%' + scope_id?) */
157dd8c81f5Sryo #define IPSEC_ADDRSTRLEN (INET6_ADDRSTRLEN + 11)
158dd8c81f5Sryo /* buffer size for ipsec_logsastr() */
159dd8c81f5Sryo #define IPSEC_LOGSASTRLEN 192
160dd8c81f5Sryo
16174029031Sjonathan /* according to IANA assignment, port 0x0000 and proto 0xff are reserved. */
16274029031Sjonathan #define IPSEC_PORT_ANY 0
16374029031Sjonathan #define IPSEC_ULPROTO_ANY 255
16474029031Sjonathan #define IPSEC_PROTO_ANY 255
16574029031Sjonathan
16674029031Sjonathan /* mode of security protocol */
16774029031Sjonathan /* NOTE: DON'T use IPSEC_MODE_ANY at SPD. It's only use in SAD */
16874029031Sjonathan #define IPSEC_MODE_ANY 0 /* i.e. wildcard. */
16974029031Sjonathan #define IPSEC_MODE_TRANSPORT 1
17074029031Sjonathan #define IPSEC_MODE_TUNNEL 2
171887b782bSjonathan #define IPSEC_MODE_TCPMD5 3 /* TCP MD5 mode */
17274029031Sjonathan
17374029031Sjonathan /*
17474029031Sjonathan * Direction of security policy.
17574029031Sjonathan * NOTE: Since INVALID is used just as flag.
17674029031Sjonathan * The other are used for loop counter too.
17774029031Sjonathan */
17874029031Sjonathan #define IPSEC_DIR_ANY 0
17974029031Sjonathan #define IPSEC_DIR_INBOUND 1
18074029031Sjonathan #define IPSEC_DIR_OUTBOUND 2
18174029031Sjonathan #define IPSEC_DIR_MAX 3
18274029031Sjonathan #define IPSEC_DIR_INVALID 4
18374029031Sjonathan
1840df8f574Sozaki-r #define IPSEC_DIR_IS_VALID(dir) ((dir) >= 0 && (dir) <= IPSEC_DIR_MAX)
1850df8f574Sozaki-r #define IPSEC_DIR_IS_INOROUT(dir) ((dir) == IPSEC_DIR_INBOUND || \
1860df8f574Sozaki-r (dir) == IPSEC_DIR_OUTBOUND)
1870df8f574Sozaki-r
18874029031Sjonathan /* Policy level */
18974029031Sjonathan /*
19074029031Sjonathan * IPSEC, ENTRUST and BYPASS are allowed for setsockopt() in PCB,
19174029031Sjonathan * DISCARD, IPSEC and NONE are allowed for setkey() in SPD.
19274029031Sjonathan * DISCARD and NONE are allowed for system default.
19374029031Sjonathan */
19474029031Sjonathan #define IPSEC_POLICY_DISCARD 0 /* discarding packet */
19574029031Sjonathan #define IPSEC_POLICY_NONE 1 /* through IPsec engine */
19674029031Sjonathan #define IPSEC_POLICY_IPSEC 2 /* do IPsec */
19774029031Sjonathan #define IPSEC_POLICY_ENTRUST 3 /* consulting SPD if present. */
19874029031Sjonathan #define IPSEC_POLICY_BYPASS 4 /* only for privileged socket. */
19974029031Sjonathan
20074029031Sjonathan /* Security protocol level */
20174029031Sjonathan #define IPSEC_LEVEL_DEFAULT 0 /* reference to system default */
20274029031Sjonathan #define IPSEC_LEVEL_USE 1 /* use SA if present. */
20374029031Sjonathan #define IPSEC_LEVEL_REQUIRE 2 /* require SA. */
20474029031Sjonathan #define IPSEC_LEVEL_UNIQUE 3 /* unique SA. */
20574029031Sjonathan
20674029031Sjonathan #define IPSEC_MANUAL_REQID_MAX 0x3fff
20774029031Sjonathan /*
20874029031Sjonathan * if security policy level == unique, this id
20974029031Sjonathan * indicate to a relative SA for use, else is
21074029031Sjonathan * zero.
21174029031Sjonathan * 1 - 0x3fff are reserved for manual keying.
21274029031Sjonathan * 0 are reserved for above reason. Others is
21374029031Sjonathan * for kernel use.
21474029031Sjonathan * Note that this id doesn't identify SA
21574029031Sjonathan * by only itself.
21674029031Sjonathan */
21774029031Sjonathan #define IPSEC_REPLAYWSIZE 32
21874029031Sjonathan
21974029031Sjonathan #ifdef _KERNEL
22074029031Sjonathan
22174029031Sjonathan extern int ipsec_debug;
22268699904Srpaulo #ifdef IPSEC_DEBUG
22368699904Srpaulo extern int ipsec_replay;
22468699904Srpaulo extern int ipsec_integrity;
22568699904Srpaulo #endif
22674029031Sjonathan
22774029031Sjonathan extern struct secpolicy ip4_def_policy;
22874029031Sjonathan extern int ip4_esp_trans_deflev;
22974029031Sjonathan extern int ip4_esp_net_deflev;
23074029031Sjonathan extern int ip4_ah_trans_deflev;
23174029031Sjonathan extern int ip4_ah_net_deflev;
23274029031Sjonathan extern int ip4_ah_cleartos;
23374029031Sjonathan extern int ip4_ah_offsetmask;
23474029031Sjonathan extern int ip4_ipsec_dfbit;
23574029031Sjonathan extern int ip4_ipsec_ecn;
23674029031Sjonathan extern int crypto_support;
23774029031Sjonathan
238290dc492Sozaki-r #include <sys/syslog.h>
2396f320ea6Smaxv
2404a07f437Schristos #define DPRINTF(fmt, args...) \
2414a07f437Schristos do { \
2424a07f437Schristos if (ipsec_debug) \
2434a07f437Schristos log(LOG_DEBUG, "%s: " fmt, __func__, ##args); \
2444a07f437Schristos } while (/*CONSTCOND*/0)
24574029031Sjonathan
246290dc492Sozaki-r #define IPSECLOG(level, fmt, args...) \
247290dc492Sozaki-r do { \
248290dc492Sozaki-r if (ipsec_debug) \
249290dc492Sozaki-r log(level, "%s: " fmt, __func__, ##args); \
2504a07f437Schristos } while (/*CONSTCOND*/0)
251290dc492Sozaki-r
2526f320ea6Smaxv #define ipsec_indone(m) \
2536f320ea6Smaxv ((m->m_flags & M_AUTHIPHDR) || (m->m_flags & M_DECRYPTED))
2546f320ea6Smaxv #define ipsec_outdone(m) \
2555c987100Smaxv (m_tag_find((m), PACKET_TAG_IPSEC_OUT_DONE) != NULL)
2566f320ea6Smaxv
257e2f99c2dSknakahara static __inline bool
ipsec_skip_pfil(struct mbuf * m)258e2f99c2dSknakahara ipsec_skip_pfil(struct mbuf *m)
259e2f99c2dSknakahara {
260e2f99c2dSknakahara bool rv;
261e2f99c2dSknakahara
262e2f99c2dSknakahara if (ipsec_indone(m) &&
263e2f99c2dSknakahara ((m->m_pkthdr.pkthdr_flags & PKTHDR_FLAG_IPSEC_SKIP_PFIL) != 0)) {
264e2f99c2dSknakahara m->m_pkthdr.pkthdr_flags &= ~PKTHDR_FLAG_IPSEC_SKIP_PFIL;
265e2f99c2dSknakahara rv = true;
266e2f99c2dSknakahara } else {
267e2f99c2dSknakahara rv = false;
268e2f99c2dSknakahara }
269e2f99c2dSknakahara
270e2f99c2dSknakahara return rv;
271e2f99c2dSknakahara }
272e2f99c2dSknakahara
2730a648e9cSdegroote void ipsec_pcbconn(struct inpcbpolicy *);
2740a648e9cSdegroote void ipsec_pcbdisconn(struct inpcbpolicy *);
2750a648e9cSdegroote void ipsec_invalpcbcacheall(void);
276ce5ecc33Sthorpej
27774029031Sjonathan struct inpcb;
278c1e00d7dSozaki-r int ipsec4_output(struct mbuf *, struct inpcb *, int, u_long *, bool *, bool *, bool *);
279f813c44dSmaxv
280b494441dSozaki-r int ipsec_ip_input_checkpolicy(struct mbuf *, bool);
281f813c44dSmaxv void ipsec_mtu(struct mbuf *, int *);
282890dda53Sknakahara #ifdef INET6
283890dda53Sknakahara void ipsec6_udp_cksum(struct mbuf *);
284890dda53Sknakahara #endif
28574029031Sjonathan
28674029031Sjonathan struct inpcb;
28719f9cae6Smaxv int ipsec_init_pcbpolicy(struct socket *so, struct inpcbpolicy **);
28876b45020Smaxv int ipsec_copy_policy(const struct inpcbpolicy *, struct inpcbpolicy *);
289dd877261Schristos u_int ipsec_get_reqlevel(const struct ipsecrequest *);
29074029031Sjonathan
2910e390eeeSozaki-r int ipsec_set_policy(struct inpcb *, const void *, size_t, kauth_cred_t);
2920e390eeeSozaki-r int ipsec_get_policy(struct inpcb *, const void *, size_t, struct mbuf **);
2930e390eeeSozaki-r int ipsec_delete_pcbpolicy(struct inpcb *);
2940e390eeeSozaki-r int ipsec_in_reject(struct mbuf *, struct inpcb *);
29574029031Sjonathan
29676b45020Smaxv struct secasvar *ipsec_lookup_sa(const struct ipsecrequest *,
29776b45020Smaxv const struct mbuf *);
29874029031Sjonathan
29974029031Sjonathan struct secas;
30074029031Sjonathan struct tcpcb;
301bbd82ed1Sdrochner int ipsec_chkreplay(u_int32_t, const struct secasvar *);
302bbd82ed1Sdrochner int ipsec_updatereplay(u_int32_t, const struct secasvar *);
30374029031Sjonathan
3040e390eeeSozaki-r size_t ipsec_hdrsiz(struct mbuf *, u_int, struct inpcb *);
3050a648e9cSdegroote size_t ipsec4_hdrsiz_tcp(struct tcpcb *);
30674029031Sjonathan
30774029031Sjonathan union sockaddr_union;
308dd8c81f5Sryo const char *ipsec_address(const union sockaddr_union* sa, char *, size_t);
309dd8c81f5Sryo const char *ipsec_logsastr(const struct secasvar *, char *, size_t);
31074029031Sjonathan
31174029031Sjonathan /* NetBSD protosw ctlin entrypoint */
3120a648e9cSdegroote void *esp4_ctlinput(int, const struct sockaddr *, void *);
3130a648e9cSdegroote void *ah4_ctlinput(int, const struct sockaddr *, void *);
31474029031Sjonathan
31564e64168Sozaki-r void ipsec_output_init(void);
31674029031Sjonathan struct m_tag;
31715652348Smaxv void ipsec4_common_input(struct mbuf *m, int, int);
31876b45020Smaxv int ipsec4_common_input_cb(struct mbuf *, struct secasvar *, int, int);
31983c2b87aSozaki-r int ipsec4_process_packet(struct mbuf *, const struct ipsecrequest *, u_long *);
32083c2b87aSozaki-r int ipsec_process_done(struct mbuf *, const struct ipsecrequest *,
321c535599fSknakahara struct secasvar *, int);
32276b45020Smaxv
3230a648e9cSdegroote struct mbuf *m_clone(struct mbuf *);
3240a648e9cSdegroote struct mbuf *m_makespace(struct mbuf *, int, int, int *);
32553524e44Schristos void *m_pad(struct mbuf *, int);
3260a648e9cSdegroote int m_striphdr(struct mbuf *, int, int);
32774029031Sjonathan
3286f320ea6Smaxv extern int ipsec_used __read_mostly;
3296f320ea6Smaxv extern int ipsec_enabled __read_mostly;
33074029031Sjonathan
33174029031Sjonathan #endif /* _KERNEL */
33274029031Sjonathan
33374029031Sjonathan #ifndef _KERNEL
3343712f81cSdrochner char *ipsec_set_policy(const char *, int);
3353712f81cSdrochner int ipsec_get_policylen(char *);
3363712f81cSdrochner char *ipsec_dump_policy(char *, const char *);
3370a648e9cSdegroote const char *ipsec_strerror(void);
33874029031Sjonathan #endif /* !_KERNEL */
33974029031Sjonathan
340d45a8b05Sjonathan #ifdef _KERNEL
34174029031Sjonathan /* External declarations of per-file init functions */
342ef67739aSozaki-r void ah_attach(void);
343ef67739aSozaki-r void esp_attach(void);
344ef67739aSozaki-r void ipcomp_attach(void);
345ef67739aSozaki-r void ipe4_attach(void);
346ef67739aSozaki-r void tcpsignature_attach(void);
34774029031Sjonathan
34880d40a78Sozaki-r void ipsec_attach(void);
34980d40a78Sozaki-r
35080d40a78Sozaki-r void sysctl_net_inet_ipsec_setup(struct sysctllog **);
35180d40a78Sozaki-r #ifdef INET6
35280d40a78Sozaki-r void sysctl_net_inet6_ipsec6_setup(struct sysctllog **);
35380d40a78Sozaki-r #endif
35480d40a78Sozaki-r
355d45a8b05Sjonathan #endif /* _KERNEL */
356adf9419cSelad #endif /* !_NETIPSEC_IPSEC_H_ */
357