xref: /freebsd/sys/netipsec/xform_tcp.c (revision eddfbb763ded6b5f6777335142be9a0edab628bb)
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