155d2c71bSBruce M Simpson /* $FreeBSD$ */ 255d2c71bSBruce M Simpson 3c398230bSWarner Losh /*- 455d2c71bSBruce M Simpson * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org> 555d2c71bSBruce M Simpson * 655d2c71bSBruce M Simpson * Redistribution and use in source and binary forms, with or without 755d2c71bSBruce M Simpson * modification, are permitted provided that the following conditions 855d2c71bSBruce M Simpson * are met: 955d2c71bSBruce M Simpson * 1055d2c71bSBruce M Simpson * 1. Redistributions of source code must retain the above copyright 1155d2c71bSBruce M Simpson * notice, this list of conditions and the following disclaimer. 1255d2c71bSBruce M Simpson * 2. Redistributions in binary form must reproduce the above copyright 1355d2c71bSBruce M Simpson * notice, this list of conditions and the following disclaimer in the 1455d2c71bSBruce M Simpson * documentation and/or other materials provided with the distribution. 1555d2c71bSBruce M Simpson * 3. The name of the author may not be used to endorse or promote products 1655d2c71bSBruce M Simpson * derived from this software without specific prior written permission. 1755d2c71bSBruce M Simpson * 1855d2c71bSBruce M Simpson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1955d2c71bSBruce M Simpson * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2055d2c71bSBruce M Simpson * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2155d2c71bSBruce M Simpson * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2255d2c71bSBruce M Simpson * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2355d2c71bSBruce M Simpson * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2455d2c71bSBruce M Simpson * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2555d2c71bSBruce M Simpson * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2655d2c71bSBruce M Simpson * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2755d2c71bSBruce M Simpson * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2855d2c71bSBruce M Simpson */ 2955d2c71bSBruce M Simpson 3055d2c71bSBruce M Simpson /* TCP MD5 Signature Option (RFC2385) */ 3155d2c71bSBruce M Simpson #include "opt_inet.h" 3255d2c71bSBruce M Simpson #include "opt_inet6.h" 3355d2c71bSBruce M Simpson 3455d2c71bSBruce M Simpson #include <sys/param.h> 3555d2c71bSBruce M Simpson #include <sys/systm.h> 3655d2c71bSBruce M Simpson #include <sys/mbuf.h> 3755d2c71bSBruce M Simpson #include <sys/lock.h> 3855d2c71bSBruce M Simpson #include <sys/socket.h> 3955d2c71bSBruce M Simpson #include <sys/kernel.h> 4055d2c71bSBruce M Simpson #include <sys/protosw.h> 4155d2c71bSBruce M Simpson #include <sys/sysctl.h> 427654a365SBjoern A. Zeeb #include <sys/vimage.h> 4355d2c71bSBruce M Simpson 4455d2c71bSBruce M Simpson #include <netinet/in.h> 4555d2c71bSBruce M Simpson #include <netinet/in_systm.h> 4655d2c71bSBruce M Simpson #include <netinet/ip.h> 4755d2c71bSBruce M Simpson #include <netinet/ip_var.h> 4855d2c71bSBruce M Simpson #include <netinet/tcp.h> 4955d2c71bSBruce M Simpson #include <netinet/tcp_var.h> 5055d2c71bSBruce M Simpson 5155d2c71bSBruce M Simpson #include <net/route.h> 52eddfbb76SRobert Watson #include <net/vnet.h> 53eddfbb76SRobert Watson 5455d2c71bSBruce M Simpson #include <netipsec/ipsec.h> 5555d2c71bSBruce M Simpson #include <netipsec/xform.h> 5655d2c71bSBruce M Simpson 5755d2c71bSBruce M Simpson #ifdef INET6 5855d2c71bSBruce M Simpson #include <netinet/ip6.h> 5955d2c71bSBruce M Simpson #include <netipsec/ipsec6.h> 6055d2c71bSBruce M Simpson #endif 6155d2c71bSBruce M Simpson 6255d2c71bSBruce M Simpson #include <netipsec/key.h> 6355d2c71bSBruce M Simpson #include <netipsec/key_debug.h> 6455d2c71bSBruce M Simpson 6555d2c71bSBruce M Simpson /* 6655d2c71bSBruce M Simpson * Initialize a TCP-MD5 SA. Called when the SA is being set up. 6755d2c71bSBruce M Simpson * 6855d2c71bSBruce M Simpson * We don't need to set up the tdb prefixed fields, as we don't use the 6955d2c71bSBruce M Simpson * opencrypto code; we just perform a key length check. 7055d2c71bSBruce M Simpson * 7155d2c71bSBruce M Simpson * XXX: Currently we only allow a single 'magic' SPI to be used. 7255d2c71bSBruce M Simpson * 7355d2c71bSBruce M Simpson * This allows per-host granularity without affecting the userland 7455d2c71bSBruce M Simpson * interface, which is a simple socket option toggle switch, 7555d2c71bSBruce M Simpson * TCP_SIGNATURE_ENABLE. 7655d2c71bSBruce M Simpson * 7755d2c71bSBruce M Simpson * To allow per-service granularity requires that we have a means 7855d2c71bSBruce M Simpson * of mapping port to SPI. The mandated way of doing this is to 7955d2c71bSBruce M Simpson * use SPD entries to specify packet flows which get the TCP-MD5 8055d2c71bSBruce M Simpson * treatment, however the code to do this is currently unstable 8155d2c71bSBruce M Simpson * and unsuitable for production use. 8255d2c71bSBruce M Simpson * 8355d2c71bSBruce M Simpson * Therefore we use this compromise in the meantime. 8455d2c71bSBruce M Simpson */ 8555d2c71bSBruce M Simpson static int 8655d2c71bSBruce M Simpson tcpsignature_init(struct secasvar *sav, struct xformsw *xsp) 8755d2c71bSBruce M Simpson { 8855d2c71bSBruce M Simpson int keylen; 8955d2c71bSBruce M Simpson 9055d2c71bSBruce M Simpson if (sav->spi != htonl(TCP_SIG_SPI)) { 9155d2c71bSBruce M Simpson DPRINTF(("%s: SPI must be TCP_SIG_SPI (0x1000)\n", 923a2366dcSBruce M Simpson __func__)); 9355d2c71bSBruce M Simpson return (EINVAL); 9455d2c71bSBruce M Simpson } 9555d2c71bSBruce M Simpson if (sav->alg_auth != SADB_X_AALG_TCP_MD5) { 9655d2c71bSBruce M Simpson DPRINTF(("%s: unsupported authentication algorithm %u\n", 9755d2c71bSBruce M Simpson __func__, sav->alg_auth)); 9855d2c71bSBruce M Simpson return (EINVAL); 9955d2c71bSBruce M Simpson } 10055d2c71bSBruce M Simpson if (sav->key_auth == NULL) { 10155d2c71bSBruce M Simpson DPRINTF(("%s: no authentication key present\n", __func__)); 10255d2c71bSBruce M Simpson return (EINVAL); 10355d2c71bSBruce M Simpson } 10455d2c71bSBruce M Simpson keylen = _KEYLEN(sav->key_auth); 10555d2c71bSBruce M Simpson if ((keylen < TCP_KEYLEN_MIN) || (keylen > TCP_KEYLEN_MAX)) { 10655d2c71bSBruce M Simpson DPRINTF(("%s: invalid key length %u\n", __func__, keylen)); 10755d2c71bSBruce M Simpson return (EINVAL); 10855d2c71bSBruce M Simpson } 10955d2c71bSBruce M Simpson 11055d2c71bSBruce M Simpson return (0); 11155d2c71bSBruce M Simpson } 11255d2c71bSBruce M Simpson 11355d2c71bSBruce M Simpson /* 11455d2c71bSBruce M Simpson * Paranoia. 11555d2c71bSBruce M Simpson * 11655d2c71bSBruce M Simpson * Called when the SA is deleted. 11755d2c71bSBruce M Simpson */ 11855d2c71bSBruce M Simpson static int 11955d2c71bSBruce M Simpson tcpsignature_zeroize(struct secasvar *sav) 12055d2c71bSBruce M Simpson { 12155d2c71bSBruce M Simpson 12255d2c71bSBruce M Simpson if (sav->key_auth) 123a0196c3cSGeorge V. Neville-Neil bzero(sav->key_auth->key_data, _KEYLEN(sav->key_auth)); 12455d2c71bSBruce M Simpson 12555d2c71bSBruce M Simpson sav->tdb_cryptoid = 0; 12655d2c71bSBruce M Simpson sav->tdb_authalgxform = NULL; 12755d2c71bSBruce M Simpson sav->tdb_xform = NULL; 12855d2c71bSBruce M Simpson 12955d2c71bSBruce M Simpson return (0); 13055d2c71bSBruce M Simpson } 13155d2c71bSBruce M Simpson 13255d2c71bSBruce M Simpson /* 13355d2c71bSBruce M Simpson * Verify that an input packet passes authentication. 13455d2c71bSBruce M Simpson * Called from the ipsec layer. 13555d2c71bSBruce M Simpson * We do this from within tcp itself, so this routine is just a stub. 13655d2c71bSBruce M Simpson */ 13755d2c71bSBruce M Simpson static int 13855d2c71bSBruce M Simpson tcpsignature_input(struct mbuf *m, struct secasvar *sav, int skip, 13955d2c71bSBruce M Simpson int protoff) 14055d2c71bSBruce M Simpson { 14155d2c71bSBruce M Simpson 14255d2c71bSBruce M Simpson return (0); 14355d2c71bSBruce M Simpson } 14455d2c71bSBruce M Simpson 14555d2c71bSBruce M Simpson /* 14655d2c71bSBruce M Simpson * Prepend the authentication header. 14755d2c71bSBruce M Simpson * Called from the ipsec layer. 14855d2c71bSBruce M Simpson * We do this from within tcp itself, so this routine is just a stub. 14955d2c71bSBruce M Simpson */ 15055d2c71bSBruce M Simpson static int 15155d2c71bSBruce M Simpson tcpsignature_output(struct mbuf *m, struct ipsecrequest *isr, 15255d2c71bSBruce M Simpson struct mbuf **mp, int skip, int protoff) 15355d2c71bSBruce M Simpson { 15455d2c71bSBruce M Simpson 15555d2c71bSBruce M Simpson return (EINVAL); 15655d2c71bSBruce M Simpson } 15755d2c71bSBruce M Simpson 15855d2c71bSBruce M Simpson static struct xformsw tcpsignature_xformsw = { 15955d2c71bSBruce M Simpson XF_TCPSIGNATURE, XFT_AUTH, "TCPMD5", 16055d2c71bSBruce M Simpson tcpsignature_init, tcpsignature_zeroize, 16155d2c71bSBruce M Simpson tcpsignature_input, tcpsignature_output 16255d2c71bSBruce M Simpson }; 16355d2c71bSBruce M Simpson 16455d2c71bSBruce M Simpson static void 16555d2c71bSBruce M Simpson tcpsignature_attach(void) 16655d2c71bSBruce M Simpson { 16755d2c71bSBruce M Simpson 16855d2c71bSBruce M Simpson xform_register(&tcpsignature_xformsw); 16955d2c71bSBruce M Simpson } 17055d2c71bSBruce M Simpson 17155d2c71bSBruce M Simpson SYSINIT(tcpsignature_xform_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, 1723e43d2aeSBjoern A. Zeeb tcpsignature_attach, NULL); 173