Skip to content

Commit

Permalink
net/tcp: Add TCP-AO config and structures
Browse files Browse the repository at this point in the history
Introduce new kernel config option and common structures as well as
helpers to be used by TCP-AO code.

Co-developed-by: Francesco Ruggeri <fruggeri@arista.com>
Signed-off-by: Francesco Ruggeri <fruggeri@arista.com>
Co-developed-by: Salam Noureddine <noureddine@arista.com>
Signed-off-by: Salam Noureddine <noureddine@arista.com>
Signed-off-by: Dmitry Safonov <dima@arista.com>
Acked-by: David Ahern <dsahern@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
0x7f454c46 authored and davem330 committed Oct 27, 2023
1 parent 8c73b26 commit c845f5f
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 8 deletions.
9 changes: 7 additions & 2 deletions include/linux/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -447,13 +447,18 @@ struct tcp_sock {
bool syn_smc; /* SYN includes SMC */
#endif

#ifdef CONFIG_TCP_MD5SIG
/* TCP AF-Specific parts; only used by MD5 Signature support so far */
#if defined(CONFIG_TCP_MD5SIG) || defined(CONFIG_TCP_AO)
/* TCP AF-Specific parts; only used by TCP-AO/MD5 Signature support so far */
const struct tcp_sock_af_ops *af_specific;

#ifdef CONFIG_TCP_MD5SIG
/* TCP MD5 Signature Option information */
struct tcp_md5sig_info __rcu *md5sig_info;
#endif
#ifdef CONFIG_TCP_AO
struct tcp_ao_info __rcu *ao_info;
#endif
#endif

/* TCP fastopen related information */
struct tcp_fastopen_request *fastopen_req;
Expand Down
8 changes: 2 additions & 6 deletions include/net/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include <net/snmp.h>
#include <net/ip.h>
#include <net/tcp_states.h>
#include <net/tcp_ao.h>
#include <net/inet_ecn.h>
#include <net/dst.h>
#include <net/mptcp.h>
Expand Down Expand Up @@ -1688,12 +1689,7 @@ static inline void tcp_clear_all_retrans_hints(struct tcp_sock *tp)
tp->retransmit_skb_hint = NULL;
}

union tcp_md5_addr {
struct in_addr a4;
#if IS_ENABLED(CONFIG_IPV6)
struct in6_addr a6;
#endif
};
#define tcp_md5_addr tcp_ao_addr

/* - key database */
struct tcp_md5sig_key {
Expand Down
90 changes: 90 additions & 0 deletions include/net/tcp_ao.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _TCP_AO_H
#define _TCP_AO_H

#define TCP_AO_KEY_ALIGN 1
#define __tcp_ao_key_align __aligned(TCP_AO_KEY_ALIGN)

union tcp_ao_addr {
struct in_addr a4;
#if IS_ENABLED(CONFIG_IPV6)
struct in6_addr a6;
#endif
};

struct tcp_ao_hdr {
u8 kind;
u8 length;
u8 keyid;
u8 rnext_keyid;
};

struct tcp_ao_key {
struct hlist_node node;
union tcp_ao_addr addr;
u8 key[TCP_AO_MAXKEYLEN] __tcp_ao_key_align;
unsigned int tcp_sigpool_id;
unsigned int digest_size;
u8 prefixlen;
u8 family;
u8 keylen;
u8 keyflags;
u8 sndid;
u8 rcvid;
u8 maclen;
struct rcu_head rcu;
u8 traffic_keys[];
};

static inline u8 *rcv_other_key(struct tcp_ao_key *key)
{
return key->traffic_keys;
}

static inline u8 *snd_other_key(struct tcp_ao_key *key)
{
return key->traffic_keys + key->digest_size;
}

static inline int tcp_ao_maclen(const struct tcp_ao_key *key)
{
return key->maclen;
}

static inline int tcp_ao_len(const struct tcp_ao_key *key)
{
return tcp_ao_maclen(key) + sizeof(struct tcp_ao_hdr);
}

static inline unsigned int tcp_ao_digest_size(struct tcp_ao_key *key)
{
return key->digest_size;
}

static inline int tcp_ao_sizeof_key(const struct tcp_ao_key *key)
{
return sizeof(struct tcp_ao_key) + (key->digest_size << 1);
}

struct tcp_ao_info {
/* List of tcp_ao_key's */
struct hlist_head head;
/* current_key and rnext_key aren't maintained on listen sockets.
* Their purpose is to cache keys on established connections,
* saving needless lookups. Never dereference any of them from
* listen sockets.
* ::current_key may change in RX to the key that was requested by
* the peer, please use READ_ONCE()/WRITE_ONCE() in order to avoid
* load/store tearing.
* Do the same for ::rnext_key, if you don't hold socket lock
* (it's changed only by userspace request in setsockopt()).
*/
struct tcp_ao_key *current_key;
struct tcp_ao_key *rnext_key;
u32 flags;
__be32 lisn;
__be32 risn;
struct rcu_head rcu;
};

#endif /* _TCP_AO_H */
2 changes: 2 additions & 0 deletions include/uapi/linux/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,8 @@ struct tcp_diag_md5sig {
__u8 tcpm_key[TCP_MD5SIG_MAXKEYLEN];
};

#define TCP_AO_MAXKEYLEN 80

/* setsockopt(fd, IPPROTO_TCP, TCP_ZEROCOPY_RECEIVE, ...) */

#define TCP_RECEIVE_ZEROCOPY_FLAG_TLB_CLEAN_HINT 0x1
Expand Down
13 changes: 13 additions & 0 deletions net/ipv4/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,19 @@ config DEFAULT_TCP_CONG
config TCP_SIGPOOL
tristate

config TCP_AO
bool "TCP: Authentication Option (RFC5925)"
select CRYPTO
select TCP_SIGPOOL
depends on 64BIT && IPV6 != m # seq-number extension needs WRITE_ONCE(u64)
help
TCP-AO specifies the use of stronger Message Authentication Codes (MACs),
protects against replays for long-lived TCP connections, and
provides more details on the association of security with TCP
connections than TCP MD5 (See RFC5925)

If unsure, say N.

config TCP_MD5SIG
bool "TCP: MD5 Signature Option support (RFC2385)"
select CRYPTO
Expand Down

0 comments on commit c845f5f

Please sign in to comment.