ip6_ipsec.c revision 275703
11638Srgrimes/*- 250476Speter * Copyright (c) 1982, 1986, 1988, 1993 31638Srgrimes * The Regents of the University of California. All rights reserved. 4156813Sru * 5156813Sru * Redistribution and use in source and binary forms, with or without 6124747Sru * modification, are permitted provided that the following conditions 7228912Sed * are met: 8124747Sru * 1. Redistributions of source code must retain the above copyright 9124747Sru * notice, this list of conditions and the following disclaimer. 10124747Sru * 2. Redistributions in binary form must reproduce the above copyright 11124747Sru * notice, this list of conditions and the following disclaimer in the 12183442Sed * documentation and/or other materials provided with the distribution. 13231191Skevlo * 4. Neither the name of the University nor the names of its contributors 14124747Sru * may be used to endorse or promote products derived from this software 15124747Sru * without specific prior written permission. 16153366Sdavidxu * 17124747Sru * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18124747Sru * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19133673Sstefanf * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20124747Sru * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21124747Sru * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22123987Smtm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23228912Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24228912Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25228912Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26228912Sed * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27228912Sed * SUCH DAMAGE. 28228912Sed */ 29228912Sed 30228912Sed#include <sys/cdefs.h> 31228912Sed__FBSDID("$FreeBSD: head/sys/netinet6/ip6_ipsec.c 275703 2014-12-11 14:58:55Z ae $"); 32228912Sed 33228912Sed#include "opt_inet.h" 34228912Sed#include "opt_inet6.h" 35228912Sed#include "opt_ipsec.h" 36228912Sed 37228912Sed#include <sys/param.h> 38228912Sed#include <sys/systm.h> 39228912Sed#include <sys/kernel.h> 40228913Sed#include <sys/mac.h> 41228912Sed#include <sys/malloc.h> 42228912Sed#include <sys/mbuf.h> 43228912Sed#include <sys/protosw.h> 44228912Sed#include <sys/socket.h> 45228912Sed#include <sys/socketvar.h> 46124747Sru#include <sys/sysctl.h> 47124747Sru#include <sys/syslog.h> 48124747Sru 49124747Sru#include <net/if.h> 50124747Sru#include <net/if_var.h> 51124747Sru#include <net/vnet.h> 52124747Sru 53124747Sru#include <netinet/in.h> 54124747Sru#include <netinet/in_systm.h> 55124747Sru#include <netinet/in_var.h> 56124747Sru#include <netinet/ip.h> 57124747Sru#include <netinet/ip6.h> 58124747Sru#include <netinet/in_pcb.h> 59124747Sru#include <netinet/ip_var.h> 60124747Sru#include <netinet/ip_options.h> 61124747Sru 62124747Sru#include <machine/in_cksum.h> 63143658Sdas 64183442Sed#ifdef IPSEC 65183442Sed#include <netipsec/ipsec.h> 66124747Sru#include <netipsec/ipsec6.h> 67124747Sru#include <netipsec/xform.h> 68124747Sru#include <netipsec/key.h> 69124747Sru#ifdef IPSEC_DEBUG 70124747Sru#include <netipsec/key_debug.h> 71130062Spjd#else 72124747Sru#define KEYDEBUG(lev,arg) 73124747Sru#endif 74124747Sru#endif /*IPSEC*/ 75124747Sru 76124747Sru#include <netinet6/ip6_ipsec.h> 77124747Sru#include <netinet6/ip6_var.h> 78124747Sru 79124747Sruextern struct protosw inet6sw[]; 80221843Smdf 81124747Sru 82124747Sru#ifdef INET6 83124747Sru#ifdef IPSEC 84124747Sru#ifdef IPSEC_FILTERTUNNEL 85130062Spjdstatic VNET_DEFINE(int, ip6_ipsec6_filtertunnel) = 1; 86124747Sru#else 87124747Srustatic VNET_DEFINE(int, ip6_ipsec6_filtertunnel) = 0; 88124747Sru#endif 89124747Sru#define V_ip6_ipsec6_filtertunnel VNET(ip6_ipsec6_filtertunnel) 90124747Sru 91124747SruSYSCTL_DECL(_net_inet6_ipsec6); 92124747SruSYSCTL_INT(_net_inet6_ipsec6, OID_AUTO, filtertunnel, 93192926Sed CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(ip6_ipsec6_filtertunnel), 0, 94124747Sru "If set filter packets from an IPsec tunnel."); 95221843Smdf#endif /* IPSEC */ 96124747Sru#endif /* INET6 */ 97124747Sru 98124747Sru/* 99124747Sru * Check if we have to jump over firewall processing for this packet. 100124747Sru * Called from ip6_input(). 101130062Spjd * 1 = jump over firewall, 0 = packet goes through firewall. 102124747Sru */ 103124747Sruint 104124747Sruip6_ipsec_filtertunnel(struct mbuf *m) 105124747Sru{ 106124747Sru#ifdef IPSEC 107124747Sru 108124747Sru /* 109124747Sru * Bypass packet filtering for packets previously handled by IPsec. 110124747Sru */ 111192926Sed if (!V_ip6_ipsec6_filtertunnel && 112124747Sru m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL) 113221843Smdf return 1; 114124747Sru#endif 115124747Sru return 0; 116124747Sru} 117124747Sru 118124747Sru/* 119124747Sru * Check if this packet has an active SA and needs to be dropped instead 120130062Spjd * of forwarded. 121130062Spjd * Called from ip6_input(). 122124747Sru * 1 = drop packet, 0 = forward packet. 123124747Sru */ 124124747Sruint 125124747Sruip6_ipsec_fwd(struct mbuf *m) 126124747Sru{ 127124747Sru#ifdef IPSEC 128124747Sru struct m_tag *mtag; 129124747Sru struct tdb_ident *tdbi; 130124747Sru struct secpolicy *sp; 131124747Sru int error; 132221843Smdf mtag = m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL); 133221843Smdf if (mtag != NULL) { 134124747Sru tdbi = (struct tdb_ident *)(mtag + 1); 135124747Sru sp = ipsec_getpolicy(tdbi, IPSEC_DIR_INBOUND); 136124747Sru } else { 137124747Sru sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, 138124747Sru IP_FORWARDING, &error); 139124747Sru } 140124747Sru if (sp == NULL) { /* NB: can happen if error */ 141124747Sru /*XXX error stat???*/ 142124747Sru DPRINTF(("%s: no SP for forwarding\n", __func__)); /*XXX*/ 143124747Sru return 1; 144124747Sru } 145124747Sru 146124747Sru /* 147176920Sjasone * Check security policy against packet attributes. 148124747Sru */ 149154548Sjasone error = ipsec_in_reject(sp, m); 150124747Sru KEY_FREESP(&sp); 151124747Sru if (error) { 152124747Sru IP6STAT_INC(ip6s_cantforward); 153124747Sru return 1; 154124747Sru } 155124747Sru#endif /* IPSEC */ 156124747Sru return 0; 157124747Sru} 158154235Smaxim 159124747Sru/* 160176920Sjasone * Check if protocol type doesn't have a further header and do IPSEC 161124747Sru * decryption or reject right now. Protocols with further headers get 162154548Sjasone * their IPSEC treatment within the protocol specific processing. 163124747Sru * Called from ip6_input(). 164124747Sru * 1 = drop packet, 0 = continue processing packet. 165124747Sru */ 166124747Sruint 167124747Sruip6_ipsec_input(struct mbuf *m, int nxt) 168124747Sru{ 169124747Sru#ifdef IPSEC 170124747Sru struct secpolicy *sp; 171124747Sru int error; 172124747Sru /* 173124747Sru * enforce IPsec policy checking if we are seeing last header. 174124747Sru * note that we do not visit this with protocols with pcb layer 175124747Sru * code - like udp/tcp/raw ip. 176124747Sru */ 177124747Sru if ((inet6sw[ip6_protox[nxt]].pr_flags & PR_LASTHDR) != 0 && 178124747Sru ipsec6_in_reject(m, NULL)) { 179124747Sru sp = ipsec_getpolicybyaddr(m, IPSEC_DIR_INBOUND, 180124747Sru IP_FORWARDING, &error); 181124747Sru if (sp != NULL) { 182124747Sru /* 18360435Sphantom * Check security policy against packet attributes. 184177714Sru */ 185124747Sru error = ipsec_in_reject(sp, m); 186201892Sdelphij KEY_FREESP(&sp); 187146348Skeramida } else { 188124747Sru /* XXX error stat??? */ 189201892Sdelphij error = EINVAL; 190124747Sru DPRINTF(("%s: no SP, packet discarded\n", __func__));/*XXX*/ 191124747Sru } 192135458Sru if (error != 0) 193126000Smtm return (1); 194124747Sru } 195124747Sru#endif /* IPSEC */ 196124747Sru return (0); 197124747Sru} 198124747Sru 199124747Sru/* 200124747Sru * Called from ip6_output(). 201124747Sru * 1 = drop packet, 0 = continue processing packet, 202124747Sru * -1 = packet was reinjected and stop processing packet 203124747Sru */ 204124747Sru 205124747Sruint 206124747Sruip6_ipsec_output(struct mbuf **m, struct inpcb *inp, int *flags, int *error, 207124747Sru struct ifnet **ifp) 208124747Sru{ 209239486Sdavidxu#ifdef IPSEC 210124747Sru struct secpolicy *sp; 211218414Sjkim 212124747Sru /* 213124747Sru * Check the security policy (SP) for the packet and, if 214124747Sru * required, do IPsec-related processing. There are two 215124747Sru * cases here; the first time a packet is sent through 216124747Sru * it will be untagged and handled by ipsec4_checkpolicy. 217124747Sru * If the packet is resubmitted to ip6_output (e.g. after 218124747Sru * AH, ESP, etc. processing), there will be a tag to bypass 219124747Sru * the lookup and related policy checking. 220124747Sru */ 221124747Sru if (m_tag_find(*m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL) { 222124747Sru *error = 0; 223124747Sru return (0); 224124747Sru } 225124747Sru sp = ipsec4_checkpolicy(*m, IPSEC_DIR_OUTBOUND, *flags, error, inp); 226124747Sru /* 227124747Sru * There are four return cases: 228124747Sru * sp != NULL apply IPsec policy 229124747Sru * sp == NULL, error == 0 no IPsec handling needed 230124747Sru * sp == NULL, error == -EINVAL discard packet w/o error 231124747Sru * sp == NULL, error != 0 discard packet, report error 232124747Sru */ 233124747Sru if (sp != NULL) { 234124747Sru /* 235124747Sru * Do delayed checksums now because we send before 236124747Sru * this is done in the normal processing path. 237124747Sru */ 238124747Sru#ifdef INET 239124747Sru if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) { 240124747Sru in_delayed_cksum(*m); 241124747Sru (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA; 242124747Sru } 243124747Sru#endif 244124747Sru if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA_IPV6) { 245124837Smtm in6_delayed_cksum(*m, (*m)->m_pkthdr.len - sizeof(struct ip6_hdr), 246124837Smtm sizeof(struct ip6_hdr)); 247124747Sru (*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA_IPV6; 248124747Sru } 249124747Sru#ifdef SCTP 250162420Smaxim if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP_IPV6) { 251162420Smaxim sctp_delayed_cksum(*m, sizeof(struct ip6_hdr)); 25260435Sphantom (*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP_IPV6; 253201892Sdelphij } 254201892Sdelphij#endif 255201892Sdelphij 256124747Sru /* NB: callee frees mbuf */ 257124747Sru *error = ipsec6_process_packet(*m, sp->req); 258124747Sru 259124747Sru if (*error == EJUSTRETURN) { 260124747Sru /* 261124747Sru * We had a SP with a level of 'use' and no SA. We 262124747Sru * will just continue to process the packet without 263124747Sru * IPsec processing. 264124747Sru */ 265124747Sru *error = 0; 266124747Sru goto done; 267124747Sru } 268124747Sru 269124747Sru /* 270124747Sru * Preserve KAME behaviour: ENOENT can be returned 271124747Sru * when an SA acquire is in progress. Don't propagate 272124747Sru * this to user-level; it confuses applications. 273124747Sru * 274124747Sru * XXX this will go away when the SADB is redone. 275201892Sdelphij */ 276201892Sdelphij if (*error == ENOENT) 277126000Smtm *error = 0; 278126000Smtm goto reinjected; 279126000Smtm } else { /* sp == NULL */ 280126000Smtm if (*error != 0) { 281135458Sru /* 282135458Sru * Hack: -EINVAL is used to signal that a packet 283124747Sru * should be silently discarded. This is typically 284207816Sjilles * because we asked key management for an SA and 285207816Sjilles * it was delayed (e.g. kicked up to IKE). 286207816Sjilles */ 287207816Sjilles if (*error == -EINVAL) 288207816Sjilles *error = 0; 289124747Sru goto bad; 290124747Sru } 291124747Sru /* No IPsec processing for this packet. */ 292124747Sru } 293124747Srudone: 294124747Sru if (sp != NULL) 295124747Sru KEY_FREESP(&sp); 296124747Sru return 0; 297124747Srureinjected: 298124747Sru if (sp != NULL) 299124747Sru KEY_FREESP(&sp); 300124747Sru return -1; 301124747Srubad: 302124747Sru if (sp != NULL) 303124747Sru KEY_FREESP(&sp); 304124837Smtm return 1; 305124837Smtm#endif /* IPSEC */ 306124837Smtm return 0; 307124747Sru} 308124747Sru 309124747Sru#if 0 310212459Sdavidxu/* 311124535Sru * Compute the MTU for a forwarded packet that gets IPSEC encapsulated. 312124535Sru * Called from ip_forward(). 3131638Srgrimes * Returns MTU suggestion for ICMP needfrag reply. 314 */ 315int 316ip6_ipsec_mtu(struct mbuf *m) 317{ 318 int mtu = 0; 319 /* 320 * If the packet is routed over IPsec tunnel, tell the 321 * originator the tunnel MTU. 322 * tunnel MTU = if MTU - sizeof(IP) - ESP/AH hdrsiz 323 * XXX quickhack!!! 324 */ 325#ifdef IPSEC 326 struct secpolicy *sp = NULL; 327 int ipsecerror; 328 int ipsechdr; 329 struct route *ro; 330 sp = ipsec_getpolicybyaddr(m, 331 IPSEC_DIR_OUTBOUND, 332 IP_FORWARDING, 333 &ipsecerror); 334 if (sp != NULL) { 335 /* count IPsec header size */ 336 ipsechdr = ipsec_hdrsiz(m, IPSEC_DIR_OUTBOUND, NULL); 337 338 /* 339 * find the correct route for outer IPv4 340 * header, compute tunnel MTU. 341 */ 342 if (sp->req != NULL && 343 sp->req->sav != NULL && 344 sp->req->sav->sah != NULL) { 345 ro = &sp->req->sav->sah->route_cache.sa_route; 346 if (ro->ro_rt && ro->ro_rt->rt_ifp) { 347 mtu = ro->ro_rt->rt_mtu ? ro->ro_rt->rt_mtu : 348 ro->ro_rt->rt_ifp->if_mtu; 349 mtu -= ipsechdr; 350 } 351 } 352 KEY_FREESP(&sp); 353 } 354#endif /* IPSEC */ 355 /* XXX else case missing. */ 356 return mtu; 357} 358#endif 359