All of lore.kernel.org
 help / color / mirror / Atom feed
From: Leonard Crestez <cdleonard@gmail.com>
To: David Ahern <dsahern@kernel.org>,
	Eric Dumazet <edumazet@google.com>,
	Dmitry Safonov <0x7f454c46@gmail.com>
Cc: Francesco Ruggeri <fruggeri@arista.com>,
	Salam Noureddine <noureddine@arista.com>,
	Philip Paeps <philip@trouble.is>, Shuah Khan <shuah@kernel.org>,
	"David S. Miller" <davem@davemloft.net>,
	Herbert Xu <herbert@gondor.apana.org.au>,
	Kuniyuki Iwashima <kuniyu@amazon.co.jp>,
	Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>,
	Jakub Kicinski <kuba@kernel.org>,
	Yuchung Cheng <ycheng@google.com>,
	Mat Martineau <mathew.j.martineau@linux.intel.com>,
	Christoph Paasch <cpaasch@apple.com>,
	Ivan Delalande <colona@arista.com>,
	Caowangbao <caowangbao@huawei.com>,
	Priyaranjan Jha <priyarjha@google.com>,
	netdev@vger.kernel.org, linux-crypto@vger.kernel.org,
	linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH v8 16/26] tcp: authopt: Add send/recv lifetime support
Date: Mon,  5 Sep 2022 10:05:52 +0300	[thread overview]
Message-ID: <c6945ec39cb040be8a60e1da1e7ad15d95df5c08.1662361354.git.cdleonard@gmail.com> (raw)
In-Reply-To: <cover.1662361354.git.cdleonard@gmail.com>

These fields are modeled on RFC8177. This allows the kernel to handle
key expiration internally instead of relying on userspace changing the
NORECV/NOSEND flags on a timer.

Signed-off-by: Leonard Crestez <cdleonard@gmail.com>
---
 include/net/tcp_authopt.h |  9 +++++++++
 include/uapi/linux/tcp.h  | 21 ++++++++++++++++++++-
 net/ipv4/tcp_authopt.c    | 39 ++++++++++++++++++++++++++++++++++++---
 3 files changed, 65 insertions(+), 4 deletions(-)

diff --git a/include/net/tcp_authopt.h b/include/net/tcp_authopt.h
index 6260c3ef6864..6ef893e75ee4 100644
--- a/include/net/tcp_authopt.h
+++ b/include/net/tcp_authopt.h
@@ -53,10 +53,19 @@ struct tcp_authopt_key_info {
 	int prefixlen;
 	/** @addr: Same as &tcp_authopt_key.addr */
 	struct sockaddr_storage addr;
 	/** @alg: Algorithm implementation matching alg_id */
 	struct tcp_authopt_alg_imp *alg;
+	/** @alg: Algorithm implementation matching alg_id */
+	/** @send_lifetime_begin: Beginning of send lifetime */
+	u64 send_lifetime_begin;
+	/** @send_lifetime_end: End of send lifetime */
+	u64 send_lifetime_end;
+	/** @recv_lifetime_begin: Beginning of recv lifetime */
+	u64 recv_lifetime_begin;
+	/** @recv_lifetime_end: End of recv lifetime */
+	u64 recv_lifetime_end;
 };
 
 /**
  * struct tcp_authopt_info - Per-socket information regarding tcp_authopt
  *
diff --git a/include/uapi/linux/tcp.h b/include/uapi/linux/tcp.h
index 274ddfefd6de..52e6293048f5 100644
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -373,20 +373,28 @@ struct tcp_authopt {
  * @TCP_AUTHOPT_KEY_ADDR_BIND: Key only valid for `tcp_authopt.addr`
  * @TCP_AUTHOPT_KEY_IFINDEX: Key only valid for `tcp_authopt.ifindex`
  * @TCP_AUTHOPT_KEY_NOSEND: Key invalid for send (expired)
  * @TCP_AUTHOPT_KEY_NORECV: Key invalid for recv (expired)
  * @TCP_AUTHOPT_KEY_PREFIXLEN: Valid value in `tcp_authopt.prefixlen`, otherwise
- * match full address length
+ * always match full address length
+ * @TCP_AUTHOPT_KEY_SEND_LIFETIME_BEGIN: Valid value in `tcp_authopt.send_lifetime_begin`
+ * @TCP_AUTHOPT_KEY_SEND_LIFETIME_END: Valid value in `tcp_authopt.send_lifetime_end`
+ * @TCP_AUTHOPT_KEY_RECV_LIFETIME_BEGIN: Valid value in `tcp_authopt.recv_lifetime_begin`
+ * @TCP_AUTHOPT_KEY_RECV_LIFETIME_END: Valid value in `tcp_authopt.recv_lifetime_end`
  */
 enum tcp_authopt_key_flag {
 	TCP_AUTHOPT_KEY_DEL = (1 << 0),
 	TCP_AUTHOPT_KEY_EXCLUDE_OPTS = (1 << 1),
 	TCP_AUTHOPT_KEY_ADDR_BIND = (1 << 2),
 	TCP_AUTHOPT_KEY_IFINDEX = (1 << 3),
 	TCP_AUTHOPT_KEY_NOSEND = (1 << 4),
 	TCP_AUTHOPT_KEY_NORECV = (1 << 5),
 	TCP_AUTHOPT_KEY_PREFIXLEN = (1 << 6),
+	TCP_AUTHOPT_KEY_SEND_LIFETIME_BEGIN = (1 << 7),
+	TCP_AUTHOPT_KEY_SEND_LIFETIME_END = (1 << 8),
+	TCP_AUTHOPT_KEY_RECV_LIFETIME_BEGIN = (1 << 9),
+	TCP_AUTHOPT_KEY_RECV_LIFETIME_END = (1 << 10),
 };
 
 /**
  * enum tcp_authopt_alg - Algorithms for TCP Authentication Option
  */
@@ -408,10 +416,13 @@ enum tcp_authopt_alg {
  * - recv_id
  * - addr (iff TCP_AUTHOPT_KEY_ADDR_BIND)
  *
  * RFC5925 requires that key ids must not overlap for the same TCP connection.
  * This is not enforced by linux.
+ *
+ * Key validity times are optional. When specified they are interpreted as "wall
+ * time" and compared to CLOCK_REALTIME.
  */
 struct tcp_authopt_key {
 	/** @flags: Combination of &enum tcp_authopt_key_flag */
 	__u32	flags;
 	/** @send_id: keyid value for send */
@@ -444,10 +455,18 @@ struct tcp_authopt_key {
 	 *
 	 * Without the TCP_AUTHOPT_KEY_PREFIXLEN flag this is ignored and a full
 	 * address match is performed.
 	 */
 	int	prefixlen;
+	/** @send_lifetime_begin: Beginning of send lifetime */
+	__u64	send_lifetime_begin;
+	/** @send_lifetime_end: End of send lifetime */
+	__u64	send_lifetime_end;
+	/** @recv_lifetime_begin: Beginning of recv lifetime */
+	__u64	recv_lifetime_begin;
+	/** @recv_lifetime_end: End of recv lifetime */
+	__u64	recv_lifetime_end;
 };
 
 /* setsockopt(fd, IPPROTO_TCP, TCP_ZEROCOPY_RECEIVE, ...) */
 
 #define TCP_RECEIVE_ZEROCOPY_FLAG_TLB_CLEAN_HINT 0x1
diff --git a/net/ipv4/tcp_authopt.c b/net/ipv4/tcp_authopt.c
index daeecb64c89e..2bb7b2356e50 100644
--- a/net/ipv4/tcp_authopt.c
+++ b/net/ipv4/tcp_authopt.c
@@ -242,10 +242,33 @@ void tcp_authopt_clear(struct sock *sk)
 	if (info) {
 		tcp_authopt_free(sk, info);
 		tcp_sk(sk)->authopt_info = NULL;
 	}
 }
+
+static bool key_valid_for_send(struct tcp_authopt_key_info *key, ktime_t now)
+{
+	if (key->flags & TCP_AUTHOPT_KEY_NOSEND)
+		return false;
+	if (key->flags & TCP_AUTHOPT_KEY_SEND_LIFETIME_BEGIN && now < key->send_lifetime_begin)
+		return false;
+	if (key->flags & TCP_AUTHOPT_KEY_SEND_LIFETIME_END && now > key->send_lifetime_end)
+		return false;
+	return true;
+}
+
+static bool key_valid_for_recv(struct tcp_authopt_key_info *key, ktime_t now)
+{
+	if (key->flags & TCP_AUTHOPT_KEY_NORECV)
+		return false;
+	if (key->flags & TCP_AUTHOPT_KEY_RECV_LIFETIME_BEGIN && now < key->recv_lifetime_begin)
+		return false;
+	if (key->flags & TCP_AUTHOPT_KEY_RECV_LIFETIME_END && now > key->recv_lifetime_end)
+		return false;
+	return true;
+}
+
 /* checks that ipv4 or ipv6 addr matches. */
 static bool ipvx_addr_match(struct sockaddr_storage *a1,
 			    struct sockaddr_storage *a2)
 {
 	if (a1->ss_family != a2->ss_family)
@@ -384,10 +407,11 @@ static bool better_key_match(struct tcp_authopt_key_info *old, struct tcp_authop
 static struct tcp_authopt_key_info *tcp_authopt_lookup_send(struct netns_tcp_authopt *net,
 							    const struct sock *addr_sk)
 {
 	struct tcp_authopt_key_info *result = NULL;
 	struct tcp_authopt_key_info *key;
+	time64_t now = ktime_get_real_seconds();
 	int l3index = -1;
 
 	hlist_for_each_entry_rcu(key, &net->head, node, 0) {
 		if (key->flags & TCP_AUTHOPT_KEY_ADDR_BIND)
 			if (!tcp_authopt_key_match_sk_addr(key, addr_sk))
@@ -397,11 +421,11 @@ static struct tcp_authopt_key_info *tcp_authopt_lookup_send(struct netns_tcp_aut
 				l3index = l3mdev_master_ifindex_by_index(sock_net(addr_sk),
 									 addr_sk->sk_bound_dev_if);
 			if (l3index != key->l3index)
 				continue;
 		}
-		if (key->flags & TCP_AUTHOPT_KEY_NOSEND)
+		if (!key_valid_for_send(key, now))
 			continue;
 		if (better_key_match(result, key))
 			result = key;
 		else if (result)
 			net_warn_ratelimited("ambiguous tcp authentication keys configured for send\n");
@@ -555,11 +579,15 @@ int tcp_get_authopt_val(struct sock *sk, struct tcp_authopt *opt)
 	TCP_AUTHOPT_KEY_EXCLUDE_OPTS | \
 	TCP_AUTHOPT_KEY_ADDR_BIND | \
 	TCP_AUTHOPT_KEY_IFINDEX | \
 	TCP_AUTHOPT_KEY_PREFIXLEN | \
 	TCP_AUTHOPT_KEY_NOSEND | \
-	TCP_AUTHOPT_KEY_NORECV)
+	TCP_AUTHOPT_KEY_NORECV | \
+	TCP_AUTHOPT_KEY_SEND_LIFETIME_BEGIN | \
+	TCP_AUTHOPT_KEY_SEND_LIFETIME_END | \
+	TCP_AUTHOPT_KEY_RECV_LIFETIME_BEGIN | \
+	TCP_AUTHOPT_KEY_RECV_LIFETIME_END)
 
 static bool ipv6_addr_is_prefix(struct in6_addr *addr, int plen)
 {
 	struct in6_addr copy;
 
@@ -690,10 +718,14 @@ int tcp_set_authopt_key(struct sock *sk, sockptr_t optval, unsigned int optlen)
 	key_info->keylen = opt.keylen;
 	memcpy(key_info->key, opt.key, opt.keylen);
 	memcpy(&key_info->addr, &opt.addr, sizeof(key_info->addr));
 	key_info->l3index = l3index;
 	key_info->prefixlen = prefixlen;
+	key_info->send_lifetime_begin = opt.send_lifetime_begin;
+	key_info->send_lifetime_end = opt.send_lifetime_end;
+	key_info->recv_lifetime_begin = opt.recv_lifetime_begin;
+	key_info->recv_lifetime_end = opt.recv_lifetime_end;
 	hlist_add_head_rcu(&key_info->node, &net->head);
 	mutex_unlock(&net->mutex);
 
 	return 0;
 }
@@ -1480,10 +1512,11 @@ static struct tcp_authopt_key_info *tcp_authopt_lookup_recv(struct sock *sk,
 							    bool *anykey)
 {
 	struct tcp_authopt_key_info *result = NULL;
 	struct tcp_authopt_key_info *key;
 	int l3index = -1;
+	time64_t now = ktime_get_real_seconds();
 
 	*anykey = false;
 	/* multiple matches will cause occasional failures */
 	hlist_for_each_entry_rcu(key, &net->head, node, 0) {
 		if (key->flags & TCP_AUTHOPT_KEY_ADDR_BIND &&
@@ -1504,11 +1537,11 @@ static struct tcp_authopt_key_info *tcp_authopt_lookup_recv(struct sock *sk,
 			if (l3index != key->l3index)
 				continue;
 		}
 		*anykey = true;
 		// If only keys with norecv flag are present still consider that
-		if (key->flags & TCP_AUTHOPT_KEY_NORECV)
+		if (!key_valid_for_recv(key, now))
 			continue;
 		if (recv_id >= 0 && key->recv_id != recv_id)
 			continue;
 		if (better_key_match(result, key))
 			result = key;
-- 
2.25.1


  parent reply	other threads:[~2022-09-05  7:08 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-05  7:05 [PATCH v8 00/26] tcp: Initial support for RFC5925 auth option Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 01/26] tcp: authopt: Initial support and key management Leonard Crestez
2022-09-06 22:57   ` Eric Dumazet
2022-09-07 16:19     ` Leonard Crestez
2022-09-07 16:28       ` Eric Dumazet
2022-09-07 18:09         ` Leonard Crestez
2022-09-08  6:35   ` Paolo Abeni
2022-09-08 10:47     ` Leonard Crestez
2022-09-08 10:53       ` David Ahern
2022-09-05  7:05 ` [PATCH v8 02/26] docs: Add user documentation for tcp_authopt Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 03/26] tcp: authopt: Add crypto initialization Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 04/26] tcp: Refactor tcp_sig_hash_skb_data for AO Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 05/26] tcp: authopt: Compute packet signatures Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 06/26] tcp: Refactor tcp_inbound_md5_hash into tcp_inbound_sig_hash Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 07/26] tcp: authopt: Hook into tcp core Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 08/26] tcp: authopt: Disable via sysctl by default Leonard Crestez
2022-09-06 23:11   ` Eric Dumazet
2022-09-07 16:53     ` Leonard Crestez
2022-09-07 17:04       ` Eric Dumazet
2022-09-07 17:58         ` Leonard Crestez
2022-09-07 22:49     ` Herbert Xu
2022-09-07 22:58       ` Eric Dumazet
2022-09-05  7:05 ` [PATCH v8 09/26] tcp: authopt: Implement Sequence Number Extension Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 10/26] tcp: ipv6: Add AO signing for tcp_v6_send_response Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 11/26] tcp: authopt: Add support for signing skb-less replies Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 12/26] tcp: ipv4: Add AO signing for " Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 13/26] tcp: authopt: Add NOSEND/NORECV flags Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 14/26] tcp: authopt: Add initial l3index support Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 15/26] tcp: authopt: Add prefixlen support Leonard Crestez
2022-09-05  7:05 ` Leonard Crestez [this message]
2022-09-05  7:05 ` [PATCH v8 17/26] tcp: authopt: Add key selection controls Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 18/26] tcp: authopt: Add v4mapped ipv6 address support Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 19/26] tcp: authopt: Add /proc/net/tcp_authopt listing all keys Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 20/26] tcp: authopt: If no keys are valid for send report an error Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 21/26] tcp: authopt: Try to respect rnextkeyid from SYN on SYNACK Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 22/26] tcp: authopt: Initial support for TCP_AUTHOPT_FLAG_ACTIVE Leonard Crestez
2022-09-05  7:05 ` [PATCH v8 23/26] tcp: authopt: Initial implementation of TCP_REPAIR_AUTHOPT Leonard Crestez
2022-09-05  7:06 ` [PATCH v8 24/26] selftests: nettest: Rename md5_prefix to key_addr_prefix Leonard Crestez
2022-09-05  7:06 ` [PATCH v8 25/26] selftests: nettest: Initial tcp_authopt support Leonard Crestez
2022-09-05  7:06 ` [PATCH v8 26/26] selftests: net/fcnal: " Leonard Crestez
2022-09-09 21:41 ` [PATCH v8 00/26] tcp: Initial support for RFC5925 auth option Salam Noureddine
2022-11-28 14:06 ` Leonard Crestez

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c6945ec39cb040be8a60e1da1e7ad15d95df5c08.1662361354.git.cdleonard@gmail.com \
    --to=cdleonard@gmail.com \
    --cc=0x7f454c46@gmail.com \
    --cc=caowangbao@huawei.com \
    --cc=colona@arista.com \
    --cc=cpaasch@apple.com \
    --cc=davem@davemloft.net \
    --cc=dsahern@kernel.org \
    --cc=edumazet@google.com \
    --cc=fruggeri@arista.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=kuba@kernel.org \
    --cc=kuniyu@amazon.co.jp \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mathew.j.martineau@linux.intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=noureddine@arista.com \
    --cc=philip@trouble.is \
    --cc=priyarjha@google.com \
    --cc=shuah@kernel.org \
    --cc=ycheng@google.com \
    --cc=yoshfuji@linux-ipv6.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.