Index: sys/netinet/tcp_syncache.c =================================================================== --- sys/netinet/tcp_syncache.c +++ sys/netinet/tcp_syncache.c @@ -1514,20 +1514,22 @@ #endif #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) - /* - * If listening socket requested TCP digests, check that received - * SYN has signature and it is correct. If signature doesn't match - * or TCP_SIGNATURE support isn't enabled, drop the packet. - */ - if (ltflags & TF_SIGNATURE) { - if ((to->to_flags & TOF_SIGNATURE) == 0) { - TCPSTAT_INC(tcps_sig_err_nosigopt); - goto done; - } + /* RFC 2385: upon receiving a signed packet, validate it */ + if (to->to_flags & TOF_SIGNATURE) { if (!TCPMD5_ENABLED() || TCPMD5_INPUT(m, th, to->to_signature) != 0) goto done; } + else if (ltflags & TF_SIGNATURE) { + /* + * The listening socket requested TCP digests, but no + * signature was provided. If there is no security + * association setup, let the packet in. + */ + if (!TCPMD5_ENABLED() || + TCPMD5_INPUT(m, NULL, NULL) != ENOENT) + goto done; + } #endif /* TCP_SIGNATURE */ /* * See if we already have an entry for this connection. @@ -1725,11 +1727,11 @@ } #if defined(IPSEC_SUPPORT) || defined(TCP_SIGNATURE) /* - * If listening socket requested TCP digests, flag this in the + * If the incoming packet has an MD5 signature, flag this in the * syncache so that syncache_respond() will do the right thing * with the SYN+ACK. */ - if (ltflags & TF_SIGNATURE) + if (to->to_flags & TOF_SIGNATURE) sc->sc_flags |= SCF_SIGNATURE; #endif /* TCP_SIGNATURE */ if (to->to_flags & TOF_SACKPERM) Index: sys/netipsec/xform_tcp.c =================================================================== --- sys/netipsec/xform_tcp.c +++ sys/netipsec/xform_tcp.c @@ -269,6 +269,11 @@ KMOD_TCPSTAT_INC(tcps_sig_err_buildsig); return (ENOENT); } + if (buf == NULL) { + key_freesav(&sav); + KMOD_TCPSTAT_INC(tcps_sig_err_nosigopt); + return (EPERM); + } /* * tcp_input() operates with TCP header fields in host * byte order. We expect them in network byte order.