0001-Import-of-RFC-2385-TCP-MD5-digest-support-from-FreeB.patch

david, 09/03/2010 07:19 PM

Download (28.5 KB)

View differences:

lib/libipsec/ipsec_dump_policy.c
191 191
	case IPPROTO_IPCOMP:
192 192
		proto = "ipcomp";
193 193
		break;
194
	case IPPROTO_TCP:
195
		proto = "tcp";
196
		break;
194 197
	default:
195 198
		__ipsec_errcode = EIPSEC_INVAL_PROTO;
196 199
		return NULL;
lib/libipsec/pfkey.c
79 79
/*
80 80
 * make and search supported algorithm structure.
81 81
 */
82
static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, };
82
static struct sadb_supported *ipsec_supported[] = { NULL, NULL, NULL, NULL};
83 83

  
84 84
static int supported_map[] = {
85 85
	SADB_SATYPE_AH,
86 86
	SADB_SATYPE_ESP,
87 87
	SADB_X_SATYPE_IPCOMP,
88
	SADB_X_SATYPE_TCPSIGNATURE,
88 89
};
89 90

  
90 91
static int
......
1166 1167
			return -1;
1167 1168
		}
1168 1169
		break;
1170
	case SADB_X_SATYPE_TCPSIGNATURE:
1171
		if (e_type != SADB_EALG_NONE) {
1172
			__ipsec_errcode = EIPSEC_INVAL_ALGS;
1173
			return -1;
1174
		}
1175
		if (a_type != SADB_X_AALG_TCP_MD5) {
1176
			__ipsec_errcode = EIPSEC_INVAL_ALGS;
1177
			return -1;
1178
		}
1179
		break;
1169 1180
	default:
1170 1181
		__ipsec_errcode = EIPSEC_INVAL_SATYPE;
1171 1182
		return -1;
......
1376 1387
		case SADB_SATYPE_AH:
1377 1388
		case SADB_SATYPE_ESP:
1378 1389
		case SADB_X_SATYPE_IPCOMP:
1390
		case SADB_X_SATYPE_TCPSIGNATURE:
1379 1391
			break;
1380 1392
		default:
1381 1393
			__ipsec_errcode = EIPSEC_INVAL_SATYPE;
......
1835 1847
	case SADB_SATYPE_ESP:
1836 1848
	case SADB_SATYPE_AH:
1837 1849
	case SADB_X_SATYPE_IPCOMP:
1850
	case SADB_X_SATYPE_TCPSIGNATURE:
1838 1851
		switch (msg->sadb_msg_type) {
1839 1852
		case SADB_X_SPDADD:
1840 1853
		case SADB_X_SPDDELETE:
lib/libipsec/pfkey_dump.c
124 124
	"ripv2",
125 125
	"mip",
126 126
	"ipcomp",
127
	"policy",
128
	"tcp",
127 129
};
128 130

  
129 131
static char *str_mode[] = {
......
162 164
	{ SADB_X_AALG_MD5, "md5", },
163 165
	{ SADB_X_AALG_SHA, "sha", },
164 166
	{ SADB_X_AALG_NULL, "null", },
167
	{ SADB_X_AALG_TCP_MD5, "tcp-md5", },
165 168
#ifdef SADB_X_AALG_SHA2_256
166 169
	{ SADB_X_AALG_SHA2_256, "hmac-sha2-256", },
167 170
#endif
lib/libipsec/policy_token.l
104 104
esp		{ yylval.num = IPPROTO_ESP; return(PROTOCOL); }
105 105
ah		{ yylval.num = IPPROTO_AH; return(PROTOCOL); }
106 106
ipcomp		{ yylval.num = IPPROTO_IPCOMP; return(PROTOCOL); }
107
tcp		{ yylval.num = IPPROTO_TCP; return(PROTOCOL); }
107 108

  
108 109
transport	{ yylval.num = IPSEC_MODE_TRANSPORT; return(MODE); }
109 110
tunnel		{ yylval.num = IPSEC_MODE_TUNNEL; return(MODE); }
share/man/man4/tcp.4
156 156
.Tn TCP
157 157
will delay sending any data at all until either the socket is closed,
158 158
or the internal send buffer is filled.
159
.It Dv TCP_SIGNATURE_ENABLE
160
This option enables the use of MD5 digests (also known as TCP-MD5)
161
on writes to the specified socket.
162
In the current release, only outgoing traffic is digested;
163
digests on incoming traffic are not verified.
164
The current default behavior for the system is to respond to a system
165
advertising this option with TCP-MD5; this may change.
166
.Pp
167
One common use for this in a DragonFlyBSD router deployment is to enable
168
based routers to interwork with Cisco equipment at peering points.
169
Support for this feature conforms to RFC 2385.
170
Only IPv4 (AF_INET) sessions are supported.
171
.Pp
172
In order for this option to function correctly, it is necessary for the
173
administrator to add a tcp-md5 key entry to the system's security
174
associations database (SADB) using the
175
.Xr setkey 8
176
utility.
177
This entry must have an SPI of 0x1000 and can therefore only be specified
178
on a per-host basis at this time.
179
.Pp
180
If an SADB entry cannot be found for the destination, the outgoing traffic
181
will have an invalid digest option prepended, and the following error message
182
will be visible on the system console:
183
.Em "tcpsignature_compute: SADB lookup failed for %d.%d.%d.%d" .
159 184
.El
160 185
.Pp
161 186
The option level for the
......
381 406
.Xr blackhole 4 ,
382 407
.Xr inet 4 ,
383 408
.Xr intro 4 ,
409
.Xr setkey 8,
384 410
.Xr ip 4
385 411
.Rs
386 412
.%A V. Jacobson
......
389 415
.%T "TCP Extensions for High Performance"
390 416
.%O RFC 1323
391 417
.Re
418
.Rs
419
.%A "A. Heffernan"
420
.%T "Protection of BGP Sessions via the TCP MD5 Signature Option"
421
.%O "RFC 2385"
422
.Re
392 423
.Sh HISTORY
393 424
The
394 425
.Nm
sys/conf/options
316 316
PPP_FILTER		opt_ppp.h
317 317
SLIP_IFF_OPTS		opt_slip.h
318 318
TCPDEBUG
319
TCP_SIGNATURE		opt_inet.h
319 320
TCP_DROP_SYNFIN		opt_tcp_input.h
320 321

  
321 322
XBONEHACK
sys/config/LINT
653 653
options                ACCEPT_FILTER_DATA
654 654
options                ACCEPT_FILTER_HTTP
655 655

  
656
# TCP_SIGNATURE adds support for RFC 2385 (TCP-MD5) digests. These are
657
# carried in TCP option 19. This option is commonly used to protect
658
# TCP sessions (e.g. BGP) where IPSEC is not available nor desirable.
659
# This is enabled on a per-socket basis using the TCP_MD5SIG socket option.
660
# This requires the use of 'device crypto', 'options IPSEC'
661
# or 'device cryptodev'.
662
options   TCP_SIGNATURE   #include support for RFC 2385
663

  
656 664
#
657 665
# TCP_DROP_SYNFIN adds support for ignoring TCP packets with SYN+FIN. This
658 666
# prevents nmap et al. from identifying the TCP/IP stack, but breaks support
sys/netinet/ip.h
211 211

  
212 212
#define	IP_MSS		576		/* default maximum segment size */
213 213

  
214
/*
215
 * This is the real IPv4 pseudo header, used for computing the TCP and UDP
216
 * checksums. For the Internet checksum, struct ipovly can be used instead.
217
 * For stronger checksums, the real thing must be used.
218
 */
219
struct ippseudo {
220
	struct	in_addr	ippseudo_src;	/* source internet address */
221
	struct	in_addr	ippseudo_dst;	/* destination internet address */
222
	u_int8_t	ippseudo_pad;	/* pad, must be zero */
223
	u_int8_t	ippseudo_p;	/* protocol */
224
	u_int16_t	ippseudo_len;	/* protocol length */
225
} __packed;
214 226
#endif
sys/netinet/ip_output.c
570 570

  
571 571
	case IPSEC_POLICY_BYPASS:
572 572
	case IPSEC_POLICY_NONE:
573
	case IPSEC_POLICY_TCP:
573 574
		/* no need to do IPsec. */
574 575
		goto skip_ipsec;
575 576

  
sys/netinet/tcp.h
110 110
#define	TCPOPT_CC		11		/* CC options: RFC-1644 */
111 111
#define TCPOPT_CCNEW		12
112 112
#define TCPOPT_CCECHO		13
113
#define TCPOPT_SIGNATURE		19      /* Keyed MD5: RFC 2385 */
114
#define TCPOLEN_SIGNATURE		18
113 115

  
114 116
/*
115 117
 * Default maximum segment size for TCP.
......
160 162
#define	TCP_MAXSEG	0x02	/* set maximum segment size */
161 163
#define TCP_NOPUSH	0x04	/* don't push last block of write */
162 164
#define TCP_NOOPT	0x08	/* don't use TCP options */
165
#define TCP_SIGNATURE_ENABLE    0x10    /* use MD5 digests (RFC2385) */
163 166

  
164 167
#endif
sys/netinet/tcp_input.c
69 69
 */
70 70

  
71 71
#include "opt_ipfw.h"		/* for ipfw_fwd		*/
72
#include "opt_inet.h"
72 73
#include "opt_inet6.h"
73 74
#include "opt_ipsec.h"
74 75
#include "opt_tcpdebug.h"
......
520 521
	struct inpcb *inp = NULL;
521 522
	u_char *optp = NULL;
522 523
	int optlen = 0;
523
	int len, tlen, off;
524
	int tlen, off;
525
	int len = 0;
524 526
	int drop_hdrlen;
525 527
	struct tcpcb *tp = NULL;
526 528
	int thflags;
......
2701 2703
				r->rblk_end = ntohl(r->rblk_end);
2702 2704
			}
2703 2705
			break;
2706
#ifdef TCP_SIGNATURE
2707
		/*
2708
		 * XXX In order to reply to a host which has set the
2709
		 * TCP_SIGNATURE option in its initial SYN, we have to
2710
		 * record the fact that the option was observed here
2711
		 * for the syncache code to perform the correct response.
2712
		 */
2713
		case TCPOPT_SIGNATURE:
2714
			if (optlen != TCPOLEN_SIGNATURE)
2715
				continue;
2716
			to->to_flags |= (TOF_SIGNATURE | TOF_SIGLEN);
2717
			break;
2718
#endif /* TCP_SIGNATURE */
2704 2719
		default:
2705 2720
			continue;
2706 2721
		}
sys/netinet/tcp_output.c
68 68
 * $DragonFly: src/sys/netinet/tcp_output.c,v 1.34 2007/04/22 01:13:14 dillon Exp $
69 69
 */
70 70

  
71
#include "opt_inet.h"
71 72
#include "opt_inet6.h"
72 73
#include "opt_ipsec.h"
73 74
#include "opt_tcpdebug.h"
......
151 152
	long len, recvwin, sendwin;
152 153
	int nsacked = 0;
153 154
	int off, flags, error;
155
	int sigoff = 0;
154 156
	struct mbuf *m;
155 157
	struct ip *ip = NULL;
156 158
	struct ipovly *ipov = NULL;
......
599 601
	     tp->reportblk.rblk_start != tp->reportblk.rblk_end))
600 602
		tcp_sack_fill_report(tp, opt, &optlen);
601 603

  
604
#ifdef TCP_SIGNATURE
605
	if (!isipv6)
606
		if (tp->t_flags & TF_SIGNATURE) {
607
			int i;
608
			u_char *bp;
609
			/*
610
			 * Initialize TCP-MD5 option (RFC2385)
611
			 */
612
			bp = (u_char *)opt + optlen;
613
			*bp++ = TCPOPT_SIGNATURE;
614
			*bp++ = TCPOLEN_SIGNATURE;
615
			sigoff = optlen + 2;
616
			for (i = 0; i < TCP_SIGLEN; i++)
617
				*bp++ = 0;
618
			optlen += TCPOLEN_SIGNATURE;
619
			/*
620
			 * Terminate options list and maintain 32-bit alignment.
621
			 */
622
			*bp++ = TCPOPT_NOP;
623
			*bp++ = TCPOPT_EOL;
624
			optlen += 2;
625
		}
626
#endif /* TCP_SIGNATURE */
602 627
	KASSERT(optlen <= TCP_MAXOLEN, ("too many TCP options"));
603 628
	hdrlen += optlen;
604 629

  
......
818 843
		tp->snd_up = tp->snd_una;		/* drag it along */
819 844
	}
820 845

  
846
#ifdef TCP_SIGNATURE
847
	if (!isipv6)
848
		if (tp->t_flags & TF_SIGNATURE)
849
			tcpsignature_compute(m, sizeof(struct ip), len, optlen,
850
					(u_char *)(th + 1) + sigoff, IPSEC_DIR_OUTBOUND);
851
#endif /* TCP_SIGNATURE */
852

  
821 853
	/*
822 854
	 * Put TCP length in extended header, and then
823 855
	 * checksum extended header and data.
sys/netinet/tcp_subr.c
69 69
 */
70 70

  
71 71
#include "opt_compat.h"
72
#include "opt_inet.h"
72 73
#include "opt_inet6.h"
73 74
#include "opt_ipsec.h"
74 75
#include "opt_tcpdebug.h"
......
126 127

  
127 128
#ifdef IPSEC
128 129
#include <netinet6/ipsec.h>
130
#include <netproto/key/key.h>
129 131
#ifdef INET6
130 132
#include <netinet6/ipsec6.h>
131 133
#endif
......
1979 1981
		bwnd = tp->t_maxseg * 2;
1980 1982
	tp->snd_bwnd = bwnd;
1981 1983
}
1984

  
1985
#ifdef TCP_SIGNATURE
1986
/*
1987
 * Compute TCP-MD5 hash of a TCPv4 segment. (RFC2385)
1988
 *
1989
 * We do this over ip, tcphdr, segment data, and the key in the SADB.
1990
 * When called from tcp_input(), we can be sure that th_sum has been
1991
 * zeroed out and verified already.
1992
 *
1993
 * This function is for IPv4 use only. Calling this function with an
1994
 * IPv6 packet in the mbuf chain will yield undefined results.
1995
 *
1996
 * Return 0 if successful, otherwise return -1.
1997
 *
1998
 * XXX The key is retrieved from the system's PF_KEY SADB, by keying a
1999
 * search with the destination IP address, and a 'magic SPI' to be
2000
 * determined by the application. This is hardcoded elsewhere to 1179
2001
 * right now. Another branch of this code exists which uses the SPD to
2002
 * specify per-application flows but it is unstable.
2003
 */
2004
int
2005
tcpsignature_compute(
2006
	struct mbuf *m,		/* mbuf chain */
2007
	int off0,		/* offset to TCP header */
2008
	int len,		/* length of TCP data */
2009
	int optlen,		/* length of TCP options */
2010
	u_char *buf,		/* storage for MD5 digest */
2011
	u_int direction)	/* direction of flow */
2012
{
2013
	struct ippseudo ippseudo;
2014
	MD5_CTX ctx;
2015
	int doff;
2016
	struct ip *ip;
2017
	struct ipovly *ipovly;
2018
	struct secasvar *sav;
2019
	struct tcphdr *th;
2020
	u_short savecsum;
2021

  
2022
	KASSERT(m != NULL, ("passed NULL mbuf. Game over."));
2023
	KASSERT(buf != NULL, ("passed NULL storage pointer for MD5 signature"));
2024
	/*
2025
	 * Extract the destination from the IP header in the mbuf.
2026
	 */
2027
	ip = mtod(m, struct ip *);
2028
	/*
2029
	 * Look up an SADB entry which matches the address found in
2030
	 * the segment.
2031
	 */
2032
	sav = key_allocsa(AF_INET, (caddr_t)&ip->ip_src, (caddr_t)&ip->ip_dst,
2033
			IPPROTO_TCP, htonl(TCP_SIG_SPI));
2034
	if (sav == NULL) {
2035
		kprintf("%s: SADB lookup failed\n", __func__);
2036
		return (EINVAL);
2037
	}
2038
	MD5Init(&ctx);
2039

  
2040
	ipovly = (struct ipovly *)ip;
2041
	th = (struct tcphdr *)((u_char *)ip + off0);
2042
	doff = off0 + sizeof(struct tcphdr) + optlen;
2043
	/*
2044
	 * Step 1: Update MD5 hash with IP pseudo-header.
2045
	 *
2046
	 * XXX The ippseudo header MUST be digested in network byte order,
2047
	 * or else we'll fail the regression test. Assume all fields we've
2048
	 * been doing arithmetic on have been in host byte order.
2049
	 * XXX One cannot depend on ipovly->ih_len here. When called from
2050
	 * tcp_output(), the underlying ip_len member has not yet been set.
2051
	 */
2052
	ippseudo.ippseudo_src = ipovly->ih_src;
2053
	ippseudo.ippseudo_dst = ipovly->ih_dst;
2054
	ippseudo.ippseudo_pad = 0;
2055
	ippseudo.ippseudo_p = IPPROTO_TCP;
2056
	ippseudo.ippseudo_len = htons(len + sizeof(struct tcphdr) + optlen);
2057
	MD5Update(&ctx, (char *)&ippseudo, sizeof(struct ippseudo));
2058
	/*
2059
	 * Step 2: Update MD5 hash with TCP header, excluding options.
2060
	 * The TCP checksum must be set to zero.
2061
	 */
2062
	savecsum = th->th_sum;
2063
	th->th_sum = 0;
2064
	MD5Update(&ctx, (char *)th, sizeof(struct tcphdr));
2065
	th->th_sum = savecsum;
2066
	/*
2067
	 * Step 3: Update MD5 hash with TCP segment data.
2068
	 *         Use m_apply() to avoid an early m_pullup().
2069
	 */
2070
	if (len > 0)
2071
		m_apply(m, doff, len, tcpsignature_apply, &ctx);
2072
	/*
2073
	 * Step 4: Update MD5 hash with shared secret.
2074
	 */
2075
	MD5Update(&ctx, _KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
2076
	MD5Final(buf, &ctx);
2077
	key_sa_recordxfer(sav, m);
2078
	key_freesav(sav);
2079
	return (0);
2080
}
2081

  
2082
int
2083
tcpsignature_apply(void *fstate, void *data, unsigned int len)
2084
{
2085

  
2086
	MD5Update((MD5_CTX *)fstate, (unsigned char *)data, len);
2087
	return (0);
2088
}
2089
#endif /* TCP_SIGNATURE */
sys/netinet/tcp_syncache.c
72 72
 * $DragonFly: src/sys/netinet/tcp_syncache.c,v 1.35 2008/11/22 11:03:35 sephe Exp $
73 73
 */
74 74

  
75
#include "opt_inet.h"
75 76
#include "opt_inet6.h"
76 77
#include "opt_ipsec.h"
77 78

  
......
848 849
	if (sc->sc_flags & SCF_SACK_PERMITTED)
849 850
		tp->t_flags |= TF_SACK_PERMITTED;
850 851

  
852
#ifdef TCP_SIGNATURE
853
	if (sc->sc_flags & SCF_SIGNATURE)
854
		tp->t_flags |= TF_SIGNATURE;
855
#endif /* TCP_SIGNATURE */
856

  
857

  
851 858
	tcp_mss(tp, sc->sc_peer_mss);
852 859

  
853 860
	/*
......
1081 1088
		sc->sc_flags |= SCF_SACK_PERMITTED;
1082 1089
	if (tp->t_flags & TF_NOOPT)
1083 1090
		sc->sc_flags = SCF_NOOPT;
1091
#ifdef TCP_SIGNATURE
1092
	/*
1093
	 * If listening socket requested TCP digests, and received SYN
1094
	 * contains the option, flag this in the syncache so that
1095
	 * syncache_respond() will do the right thing with the SYN+ACK.
1096
	 * XXX Currently we always record the option by default and will
1097
	 * attempt to use it in syncache_respond().
1098
	 */
1099
	if (to->to_flags & TOF_SIGNATURE)
1100
		sc->sc_flags = SCF_SIGNATURE;
1101
#endif /* TCP_SIGNATURE */
1084 1102

  
1085 1103
	if (syncache_respond(sc, m) == 0) {
1086 1104
		syncache_insert(sc, sch);
......
1137 1155
		    ((sc->sc_flags & SCF_TIMESTAMP) ? TCPOLEN_TSTAMP_APPA : 0) +
1138 1156
		    ((sc->sc_flags & SCF_SACK_PERMITTED) ?
1139 1157
			TCPOLEN_SACK_PERMITTED_ALIGNED : 0);
1158
#ifdef TCP_SIGNATURE
1159
				optlen += ((sc->sc_flags & SCF_SIGNATURE) ?
1160
						(TCPOLEN_SIGNATURE + 2) : 0);
1161
#endif /* TCP_SIGNATURE */
1140 1162
	}
1141 1163
	tlen = hlen + sizeof(struct tcphdr) + optlen;
1142 1164

  
......
1237 1259
		optp += TCPOLEN_TSTAMP_APPA;
1238 1260
	}
1239 1261

  
1262
#ifdef TCP_SIGNATURE
1263
	/*
1264
	 * Handle TCP-MD5 passive opener response.
1265
	 */
1266
	if (sc->sc_flags & SCF_SIGNATURE) {
1267
		u_int8_t *bp = optp;
1268
		int i;
1269

  
1270
		*bp++ = TCPOPT_SIGNATURE;
1271
		*bp++ = TCPOLEN_SIGNATURE;
1272
		for (i = 0; i < TCP_SIGLEN; i++)
1273
			*bp++ = 0;
1274
		tcpsignature_compute(m, sizeof(struct ip), 0, optlen,
1275
				optp + 2, IPSEC_DIR_OUTBOUND);
1276
		*bp++ = TCPOPT_NOP;
1277
		*bp++ = TCPOPT_EOL;
1278
		optp += TCPOLEN_SIGNATURE + 2;
1279
}
1280
#endif /* TCP_SIGNATURE */
1281

  
1240 1282
	if (sc->sc_flags & SCF_SACK_PERMITTED) {
1241 1283
		*((u_int32_t *)optp) = htonl(TCPOPT_SACK_PERMITTED_ALIGNED);
1242 1284
		optp += TCPOLEN_SACK_PERMITTED_ALIGNED;
sys/netinet/tcp_usrreq.c
69 69
 */
70 70

  
71 71
#include "opt_ipsec.h"
72
#include "opt_inet.h"
72 73
#include "opt_inet6.h"
73 74
#include "opt_tcpdebug.h"
74 75

  
......
1252 1253
		if (error)
1253 1254
			break;
1254 1255
		switch (sopt->sopt_name) {
1256
#ifdef TCP_SIGNATURE
1257
		case TCP_SIGNATURE_ENABLE:
1258
			if (optval > 0)
1259
				tp->t_flags |= TF_SIGNATURE;
1260
			else
1261
				tp->t_flags &= ~TF_SIGNATURE;
1262
			break;
1263
#endif /* TCP_SIGNATURE */
1255 1264
		case TCP_NODELAY:
1256 1265
		case TCP_NOOPT:
1257 1266
			switch (sopt->sopt_name) {
......
1309 1318

  
1310 1319
	case SOPT_GET:
1311 1320
		switch (sopt->sopt_name) {
1321
#ifdef TCP_SIGNATURE
1322
		case TCP_SIGNATURE_ENABLE:
1323
			optval = (tp->t_flags & TF_SIGNATURE) ? 1 : 0;
1324
			break;
1325
#endif /* TCP_SIGNATURE */
1312 1326
		case TCP_NODELAY:
1313 1327
			optval = tp->t_flags & TF_NODELAY;
1314 1328
			break;
sys/netinet/tcp_var.h
160 160
#define	TF_NEEDFIN	0x00000800	/* send FIN (implicit state) */
161 161
#define	TF_NOPUSH	0x00001000	/* don't push */
162 162
#define TF_SYNCACHE	0x00002000	/* syncache present */
163
/* 0x00001000 - 0x00008000 were used for T/TCP */
163
#define TF_SIGNATURE 0x00004000  /* require MD5 digests (RFC2385) */
164 164
#define	TF_MORETOCOME	0x00010000	/* More data to be appended to sock */
165 165
#define	TF_LQ_OVERFLOW	0x00020000	/* listen queue overflow */
166 166
#define	TF_LASTIDLE	0x00040000	/* connection was previously idle */
......
274 274
#define	ENTER_FASTRECOVERY(tp)	tp->t_flags |= TF_FASTRECOVERY
275 275
#define	EXIT_FASTRECOVERY(tp)	tp->t_flags &= ~TF_FASTRECOVERY
276 276

  
277
#ifdef TCP_SIGNATURE
278
/*
279
 * Defines which are needed by the xform_tcp module and tcp_[in|out]put
280
 * for SADB verification and lookup.
281
 */
282
#define TCP_SIGLEN      16      /* length of computed digest in bytes */
283
#define TCP_KEYLEN_MIN  1       /* minimum length of TCP-MD5 key */
284
#define TCP_KEYLEN_MAX  80      /* maximum length of TCP-MD5 key */
285
/*
286
 * Only a single SA per host may be specified at this time. An SPI is
287
 * needed in order for the KEY_ALLOCSA() lookup to work.
288
 */
289
#define TCP_SIG_SPI     0x1000
290
#endif /* TCP_SIGNATURE */
291

  
277 292
/*
278 293
 * TCP statistics.
279 294
 */
......
402 417
#define	TOF_SCALE		0x0020
403 418
#define	TOF_SACK_PERMITTED	0x0040
404 419
#define	TOF_SACK		0x0080
420
#define TOF_SIGNATURE   0x0100          /* signature option present */
421
#define TOF_SIGLEN      0x0200          /* sigature length valid (RFC2385) */
405 422
	u_int32_t	to_tsval;
406 423
	u_int32_t	to_tsecr;
407 424
	u_int16_t	to_mss;
......
432 449
#define SCF_TIMESTAMP		0x04		/* negotiated timestamps */
433 450
#define SCF_UNREACH		0x10		/* icmp unreachable received */
434 451
#define	SCF_SACK_PERMITTED	0x20		/* saw SACK permitted option */
452
#define SCF_SIGNATURE   0x40    /* send MD5 digests */
435 453
#define SCF_MARKER		0x80		/* not a real entry */
436 454
	TAILQ_ENTRY(syncache) sc_hash;
437 455
	TAILQ_ENTRY(syncache) sc_timerq;
......
627 645
void	 syncache_badack(struct in_conninfo *);
628 646
void	 syncache_destroy(struct tcpcb *tp);
629 647

  
648
#ifdef TCP_SIGNATURE
649
int tcpsignature_apply(void *fstate, void *data, unsigned int len);
650
int tcpsignature_compute(struct mbuf *m, int off0, int len, int tcpoptlen,
651
		u_char *buf, u_int direction);
652
#endif /* TCP_SIGNATURE */
630 653

  
631 654
extern	struct pr_usrreqs tcp_usrreqs;
632 655
extern	u_long tcp_sendspace;
sys/netinet6/ipsec.h
140 140
#define	IPSEC_MODE_ANY		0	/* i.e. wildcard. */
141 141
#define	IPSEC_MODE_TRANSPORT	1
142 142
#define	IPSEC_MODE_TUNNEL	2
143
#define IPSEC_MODE_TCPMD5 3  /* TCP MD5 mode */
143 144

  
144 145
/*
145 146
 * Direction of security policy.
......
163 164
#define IPSEC_POLICY_IPSEC	2	/* do IPsec */
164 165
#define IPSEC_POLICY_ENTRUST	3	/* consulting SPD if present. */
165 166
#define IPSEC_POLICY_BYPASS	4	/* only for privileged socket. */
167
#define IPSEC_POLICY_TCP 5 /* TCP MD5 policy */
166 168

  
167 169
/* Security protocol level */
168 170
#define	IPSEC_LEVEL_DEFAULT	0	/* reference to system default */
sys/netproto/key/key.c
2945 2945
		switch (mhp->msg->sadb_msg_satype) {
2946 2946
		case SADB_SATYPE_AH:
2947 2947
		case SADB_SATYPE_ESP:
2948
		case SADB_X_SATYPE_TCPSIGNATURE:
2948 2949
			if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) &&
2949 2950
			    sav->alg_auth != SADB_X_AALG_NULL)
2950 2951
				error = EINVAL;
......
3000 3001
			sav->key_enc = NULL;	/*just in case*/
3001 3002
			break;
3002 3003
		case SADB_SATYPE_AH:
3004
		case SADB_X_SATYPE_TCPSIGNATURE:
3003 3005
		default:
3004 3006
			error = EINVAL;
3005 3007
			break;
......
3034 3036
		break;
3035 3037
	case SADB_SATYPE_AH:
3036 3038
	case SADB_X_SATYPE_IPCOMP:
3039
	case SADB_X_SATYPE_TCPSIGNATURE:
3037 3040
		break;
3038 3041
	default:
3039 3042
		ipseclog((LOG_DEBUG, "key_setsaval: invalid SA type.\n"));
......
3213 3216
		checkmask = 4;
3214 3217
		mustmask = 4;
3215 3218
		break;
3219
	case IPPROTO_TCP:
3220
		if (sav->alg_auth != SADB_X_AALG_TCP_MD5) {
3221
			ipseclog((LOG_DEBUG, "key_mature: "
3222
				"protocol and algorithm mismated.\n"));
3223
			return(EINVAL);
3224
		}
3225
		checkmask = 0;
3226
		mustmask = 0;
3227
		break;
3216 3228
	default:
3217 3229
		ipseclog((LOG_DEBUG, "key_mature: Invalid satype.\n"));
3218 3230
		return EPROTONOSUPPORT;
......
4407 4419
		return IPPROTO_ESP;
4408 4420
	case SADB_X_SATYPE_IPCOMP:
4409 4421
		return IPPROTO_IPCOMP;
4422
	case SADB_X_SATYPE_TCPSIGNATURE:
4423
		return IPPROTO_TCP;
4410 4424
		break;
4411 4425
	default:
4412 4426
		return 0;
......
4429 4443
		return SADB_SATYPE_ESP;
4430 4444
	case IPPROTO_IPCOMP:
4431 4445
		return SADB_X_SATYPE_IPCOMP;
4446
	case IPPROTO_TCP:
4447
		return SADB_X_SATYPE_TCPSIGNATURE;
4432 4448
		break;
4433 4449
	default:
4434 4450
		return 0;
......
6757 6773
	case SADB_SATYPE_AH:
6758 6774
	case SADB_SATYPE_ESP:
6759 6775
	case SADB_X_SATYPE_IPCOMP:
6776
	case SADB_X_SATYPE_TCPSIGNATURE:
6760 6777
		switch (msg->sadb_msg_type) {
6761 6778
		case SADB_X_SPDADD:
6762 6779
		case SADB_X_SPDDELETE:
usr.sbin/setkey/parse.y
102 102
%token EOT
103 103
%token ADD GET DELETE DELETEALL FLUSH DUMP
104 104
%token ADDRESS PREFIX PORT PORTANY
105
%token UP_PROTO PR_ESP PR_AH PR_IPCOMP
105
%token UP_PROTO PR_ESP PR_AH PR_IPCOMP PR_TCP
106 106
%token F_PROTOCOL F_AUTH F_ENC F_REPLAY F_COMP F_RAWCPI
107 107
%token F_MODE MODE F_REQID
108 108
%token F_EXT EXTENSION NOCYCLICSEQ
......
114 114
%token F_POLICY PL_REQUESTS
115 115

  
116 116
%type <num> PORT PREFIX EXTENSION MODE
117
%type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP
117
%type <num> UP_PROTO PR_ESP PR_AH PR_IPCOMP PR_TCP
118 118
%type <num> ALG_AUTH ALG_ENC ALG_ENC_DESDERIV ALG_ENC_DES32IV ALG_COMP
119 119
%type <num> DECSTRING
120 120
%type <val> ADDRESS PL_REQUESTS
......
230 230
		{
231 231
			p_satype = SADB_X_SATYPE_IPCOMP;
232 232
		}
233
	|	PR_TCP
234
		{
235
			p_satype = SADB_X_SATYPE_TCPSIGNATURE;
236
		}
233 237
	;
234 238
	
235 239
spi
......
349 353
			p_key_auth_len = $1.len;
350 354
			p_key_auth = pp_key;
351 355

  
352
			if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
356
			if (p_alg_auth == SADB_X_AALG_TCP_MD5) {
357
				if ((p_key_auth_len < 1) || (p_key_auth_len >
358
					80))
359
					return -1;
360
			} else if (ipsec_check_keylen(SADB_EXT_SUPPORTED_AUTH,
353 361
					p_alg_auth,
354 362
					PFKEY_UNUNIT64(p_key_auth_len)) < 0) {
355 363
				yyerror(ipsec_strerror());
usr.sbin/setkey/setkey.8
220 220
AH based on rfc1826
221 221
.It Li ipcomp
222 222
IPCOMP
223
.It Li tcp
224
TCP-MD5 based on rfc2385
223 225
.El
224 226
.\"
225 227
.Pp
......
230 232
(with
231 233
.Li 0x
232 234
attached).
235
TCP-MD5 associations must use 0x1000 and therefore only have per-host
236
granularity at this time.
233 237
.\"
234 238
.Pp
235 239
.It Ar extensions
......
547 551
		384		ah-old: 128bit ICV (no document)
548 552
hmac-sha2-512	512		ah: 96bit ICV (no document)
549 553
		512		ah-old: 128bit ICV (no document)
554
tcp-md5		8 to 640	tcp: rfc2385
550 555
.Ed
551 556
.Pp
552 557
Followings are the list of encryption algorithms that can be used as
......
602 607
spdadd	10.0.11.41/32[21] 10.0.11.33/32[any] any
603 608
		-P out ipsec esp/tunnel/192.168.0.1-192.168.1.2/require ;
604 609

  
610
add 10.1.10.34 10.1.10.36 tcp 0x1000 -A tcp-md5 "TCP-MD5 BGP secret" ;
611

  
605 612
.Ed
606 613
.\"
607 614
.Sh DIAGNOSTICS
usr.sbin/setkey/token.l
163 163
ah-old		{ PREPROC; yylval.num = 1; return(PR_AH); }
164 164
esp-old		{ PREPROC; yylval.num = 1; return(PR_ESP); }
165 165
ipcomp		{ PREPROC; yylval.num = 0; return(PR_IPCOMP); }
166
tcp		{ PREPROC; yylval.num = 0; return(PR_TCP); }
166 167

  
167 168
	/* authentication alogorithm */
168 169
{hyphen}A	{ PREPROC; return(F_AUTH); }
......
173 174
hmac-sha2-256	{ PREPROC; yylval.num = SADB_X_AALG_SHA2_256; return(ALG_AUTH); }
174 175
hmac-sha2-384	{ PREPROC; yylval.num = SADB_X_AALG_SHA2_384; return(ALG_AUTH); }
175 176
hmac-sha2-512	{ PREPROC; yylval.num = SADB_X_AALG_SHA2_512; return(ALG_AUTH); }
177
tcp-md5	{ PREPROC; yylval.num = SADB_X_AALG_TCP_MD5; return(ALG_AUTH); }
176 178
null		{ PREPROC; yylval.num = SADB_X_AALG_NULL; return(ALG_AUTH); }
177 179

  
178 180
	/* encryption alogorithm */
179
-