Commit 26811cc9 authored by Davide Caratti's avatar Davide Caratti Committed by David S. Miller
Browse files

net: tls: export protocol version, cipher, tx_conf/rx_conf to socket diag



When an application configures kernel TLS on top of a TCP socket, it's
now possible for inet_diag_handler() to collect information regarding the
protocol version, the cipher type and TX / RX configuration, in case
INET_DIAG_INFO is requested.

Signed-off-by: default avatarDavide Caratti <dcaratti@redhat.com>
Reviewed-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 61723b39
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -431,6 +431,23 @@ static inline bool is_tx_ready(struct tls_sw_context_tx *ctx)
	return READ_ONCE(rec->tx_ready);
}

static inline u16 tls_user_config(struct tls_context *ctx, bool tx)
{
	u16 config = tx ? ctx->tx_conf : ctx->rx_conf;

	switch (config) {
	case TLS_BASE:
		return TLS_CONF_BASE;
	case TLS_SW:
		return TLS_CONF_SW;
	case TLS_HW:
		return TLS_CONF_HW;
	case TLS_HW_RECORD:
		return TLS_CONF_HW_RECORD;
	}
	return 0;
}

struct sk_buff *
tls_validate_xmit_skb(struct sock *sk, struct net_device *dev,
		      struct sk_buff *skb);
+1 −0
Original line number Diff line number Diff line
@@ -162,6 +162,7 @@ enum {
enum {
	INET_ULP_INFO_UNSPEC,
	INET_ULP_INFO_NAME,
	INET_ULP_INFO_TLS,
	__INET_ULP_INFO_MAX,
};
#define INET_ULP_INFO_MAX (__INET_ULP_INFO_MAX - 1)
+15 −0
Original line number Diff line number Diff line
@@ -109,4 +109,19 @@ struct tls12_crypto_info_aes_ccm_128 {
	unsigned char rec_seq[TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE];
};

enum {
	TLS_INFO_UNSPEC,
	TLS_INFO_VERSION,
	TLS_INFO_CIPHER,
	TLS_INFO_TXCONF,
	TLS_INFO_RXCONF,
	__TLS_INFO_MAX,
};
#define TLS_INFO_MAX (__TLS_INFO_MAX - 1)

#define TLS_CONF_BASE 1
#define TLS_CONF_SW 2
#define TLS_CONF_HW 3
#define TLS_CONF_HW_RECORD 4

#endif /* _UAPI_LINUX_TLS_H */
+64 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include <linux/netdevice.h>
#include <linux/sched/signal.h>
#include <linux/inetdevice.h>
#include <linux/inet_diag.h>

#include <net/tls.h>

@@ -835,6 +836,67 @@ static void tls_update(struct sock *sk, struct proto *p)
	}
}

static int tls_get_info(const struct sock *sk, struct sk_buff *skb)
{
	u16 version, cipher_type;
	struct tls_context *ctx;
	struct nlattr *start;
	int err;

	start = nla_nest_start_noflag(skb, INET_ULP_INFO_TLS);
	if (!start)
		return -EMSGSIZE;

	rcu_read_lock();
	ctx = rcu_dereference(inet_csk(sk)->icsk_ulp_data);
	if (!ctx) {
		err = 0;
		goto nla_failure;
	}
	version = ctx->prot_info.version;
	if (version) {
		err = nla_put_u16(skb, TLS_INFO_VERSION, version);
		if (err)
			goto nla_failure;
	}
	cipher_type = ctx->prot_info.cipher_type;
	if (cipher_type) {
		err = nla_put_u16(skb, TLS_INFO_CIPHER, cipher_type);
		if (err)
			goto nla_failure;
	}
	err = nla_put_u16(skb, TLS_INFO_TXCONF, tls_user_config(ctx, true));
	if (err)
		goto nla_failure;

	err = nla_put_u16(skb, TLS_INFO_RXCONF, tls_user_config(ctx, false));
	if (err)
		goto nla_failure;

	rcu_read_unlock();
	nla_nest_end(skb, start);
	return 0;

nla_failure:
	rcu_read_unlock();
	nla_nest_cancel(skb, start);
	return err;
}

static size_t tls_get_info_size(const struct sock *sk)
{
	size_t size = 0;

	size += nla_total_size(0) +		/* INET_ULP_INFO_TLS */
		nla_total_size(sizeof(u16)) +	/* TLS_INFO_VERSION */
		nla_total_size(sizeof(u16)) +	/* TLS_INFO_CIPHER */
		nla_total_size(sizeof(u16)) +	/* TLS_INFO_RXCONF */
		nla_total_size(sizeof(u16)) +	/* TLS_INFO_TXCONF */
		0;

	return size;
}

void tls_register_device(struct tls_device *device)
{
	spin_lock_bh(&device_spinlock);
@@ -856,6 +918,8 @@ static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = {
	.owner			= THIS_MODULE,
	.init			= tls_init,
	.update			= tls_update,
	.get_info		= tls_get_info,
	.get_info_size		= tls_get_info_size,
};

static int __init tls_register(void)