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> 4255d2c71bSBruce M Simpson 4355d2c71bSBruce M Simpson #include <netinet/in.h> 4455d2c71bSBruce M Simpson #include <netinet/in_systm.h> 4555d2c71bSBruce M Simpson #include <netinet/ip.h> 4655d2c71bSBruce M Simpson #include <netinet/ip_var.h> 4755d2c71bSBruce M Simpson #include <netinet/tcp.h> 4855d2c71bSBruce M Simpson #include <netinet/tcp_var.h> 4955d2c71bSBruce M Simpson 5055d2c71bSBruce M Simpson #include <net/route.h> 5155d2c71bSBruce M Simpson #include <netipsec/ipsec.h> 5255d2c71bSBruce M Simpson #include <netipsec/xform.h> 5355d2c71bSBruce M Simpson 5455d2c71bSBruce M Simpson #ifdef INET6 5555d2c71bSBruce M Simpson #include <netinet/ip6.h> 5655d2c71bSBruce M Simpson #include <netipsec/ipsec6.h> 5755d2c71bSBruce M Simpson #endif 5855d2c71bSBruce M Simpson 5955d2c71bSBruce M Simpson #include <netipsec/key.h> 6055d2c71bSBruce M Simpson #include <netipsec/key_debug.h> 6155d2c71bSBruce M Simpson 6255d2c71bSBruce M Simpson /* 6355d2c71bSBruce M Simpson * Initialize a TCP-MD5 SA. Called when the SA is being set up. 6455d2c71bSBruce M Simpson * 6555d2c71bSBruce M Simpson * We don't need to set up the tdb prefixed fields, as we don't use the 6655d2c71bSBruce M Simpson * opencrypto code; we just perform a key length check. 6755d2c71bSBruce M Simpson * 6855d2c71bSBruce M Simpson * XXX: Currently we only allow a single 'magic' SPI to be used. 6955d2c71bSBruce M Simpson * 7055d2c71bSBruce M Simpson * This allows per-host granularity without affecting the userland 7155d2c71bSBruce M Simpson * interface, which is a simple socket option toggle switch, 7255d2c71bSBruce M Simpson * TCP_SIGNATURE_ENABLE. 7355d2c71bSBruce M Simpson * 7455d2c71bSBruce M Simpson * To allow per-service granularity requires that we have a means 7555d2c71bSBruce M Simpson * of mapping port to SPI. The mandated way of doing this is to 7655d2c71bSBruce M Simpson * use SPD entries to specify packet flows which get the TCP-MD5 7755d2c71bSBruce M Simpson * treatment, however the code to do this is currently unstable 7855d2c71bSBruce M Simpson * and unsuitable for production use. 7955d2c71bSBruce M Simpson * 8055d2c71bSBruce M Simpson * Therefore we use this compromise in the meantime. 8155d2c71bSBruce M Simpson */ 8255d2c71bSBruce M Simpson static int 8355d2c71bSBruce M Simpson tcpsignature_init(struct secasvar *sav, struct xformsw *xsp) 8455d2c71bSBruce M Simpson { 8555d2c71bSBruce M Simpson int keylen; 8655d2c71bSBruce M Simpson 8755d2c71bSBruce M Simpson if (sav->spi != htonl(TCP_SIG_SPI)) { 8855d2c71bSBruce M Simpson DPRINTF(("%s: SPI must be TCP_SIG_SPI (0x1000)\n", 893a2366dcSBruce M Simpson __func__)); 9055d2c71bSBruce M Simpson return (EINVAL); 9155d2c71bSBruce M Simpson } 9255d2c71bSBruce M Simpson if (sav->alg_auth != SADB_X_AALG_TCP_MD5) { 9355d2c71bSBruce M Simpson DPRINTF(("%s: unsupported authentication algorithm %u\n", 9455d2c71bSBruce M Simpson __func__, sav->alg_auth)); 9555d2c71bSBruce M Simpson return (EINVAL); 9655d2c71bSBruce M Simpson } 9755d2c71bSBruce M Simpson if (sav->key_auth == NULL) { 9855d2c71bSBruce M Simpson DPRINTF(("%s: no authentication key present\n", __func__)); 9955d2c71bSBruce M Simpson return (EINVAL); 10055d2c71bSBruce M Simpson } 10155d2c71bSBruce M Simpson keylen = _KEYLEN(sav->key_auth); 10255d2c71bSBruce M Simpson if ((keylen < TCP_KEYLEN_MIN) || (keylen > TCP_KEYLEN_MAX)) { 10355d2c71bSBruce M Simpson DPRINTF(("%s: invalid key length %u\n", __func__, keylen)); 10455d2c71bSBruce M Simpson return (EINVAL); 10555d2c71bSBruce M Simpson } 10655d2c71bSBruce M Simpson 10755d2c71bSBruce M Simpson return (0); 10855d2c71bSBruce M Simpson } 10955d2c71bSBruce M Simpson 11055d2c71bSBruce M Simpson /* 11155d2c71bSBruce M Simpson * Paranoia. 11255d2c71bSBruce M Simpson * 11355d2c71bSBruce M Simpson * Called when the SA is deleted. 11455d2c71bSBruce M Simpson */ 11555d2c71bSBruce M Simpson static int 11655d2c71bSBruce M Simpson tcpsignature_zeroize(struct secasvar *sav) 11755d2c71bSBruce M Simpson { 11855d2c71bSBruce M Simpson 11955d2c71bSBruce M Simpson if (sav->key_auth) 12055d2c71bSBruce M Simpson bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth)); 12155d2c71bSBruce M Simpson 12255d2c71bSBruce M Simpson sav->tdb_cryptoid = 0; 12355d2c71bSBruce M Simpson sav->tdb_authalgxform = NULL; 12455d2c71bSBruce M Simpson sav->tdb_xform = NULL; 12555d2c71bSBruce M Simpson 12655d2c71bSBruce M Simpson return (0); 12755d2c71bSBruce M Simpson } 12855d2c71bSBruce M Simpson 12955d2c71bSBruce M Simpson /* 13055d2c71bSBruce M Simpson * Verify that an input packet passes authentication. 13155d2c71bSBruce M Simpson * Called from the ipsec layer. 13255d2c71bSBruce M Simpson * We do this from within tcp itself, so this routine is just a stub. 13355d2c71bSBruce M Simpson */ 13455d2c71bSBruce M Simpson static int 13555d2c71bSBruce M Simpson tcpsignature_input(struct mbuf *m, struct secasvar *sav, int skip, 13655d2c71bSBruce M Simpson int protoff) 13755d2c71bSBruce M Simpson { 13855d2c71bSBruce M Simpson 13955d2c71bSBruce M Simpson return (0); 14055d2c71bSBruce M Simpson } 14155d2c71bSBruce M Simpson 14255d2c71bSBruce M Simpson /* 14355d2c71bSBruce M Simpson * Prepend the authentication header. 14455d2c71bSBruce M Simpson * Called from the ipsec layer. 14555d2c71bSBruce M Simpson * We do this from within tcp itself, so this routine is just a stub. 14655d2c71bSBruce M Simpson */ 14755d2c71bSBruce M Simpson static int 14855d2c71bSBruce M Simpson tcpsignature_output(struct mbuf *m, struct ipsecrequest *isr, 14955d2c71bSBruce M Simpson struct mbuf **mp, int skip, int protoff) 15055d2c71bSBruce M Simpson { 15155d2c71bSBruce M Simpson 15255d2c71bSBruce M Simpson return (EINVAL); 15355d2c71bSBruce M Simpson } 15455d2c71bSBruce M Simpson 15555d2c71bSBruce M Simpson static struct xformsw tcpsignature_xformsw = { 15655d2c71bSBruce M Simpson XF_TCPSIGNATURE, XFT_AUTH, "TCPMD5", 15755d2c71bSBruce M Simpson tcpsignature_init, tcpsignature_zeroize, 15855d2c71bSBruce M Simpson tcpsignature_input, tcpsignature_output 15955d2c71bSBruce M Simpson }; 16055d2c71bSBruce M Simpson 16155d2c71bSBruce M Simpson static void 16255d2c71bSBruce M Simpson tcpsignature_attach(void) 16355d2c71bSBruce M Simpson { 16455d2c71bSBruce M Simpson 16555d2c71bSBruce M Simpson xform_register(&tcpsignature_xformsw); 16655d2c71bSBruce M Simpson } 16755d2c71bSBruce M Simpson 16855d2c71bSBruce M Simpson SYSINIT(tcpsignature_xform_init, SI_SUB_DRIVERS, SI_ORDER_FIRST, 16955d2c71bSBruce M Simpson tcpsignature_attach, NULL) 170