diff options
author | Davide Caratti <dcaratti@redhat.com> | 2019-08-30 06:25:49 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-09-01 02:44:28 -0400 |
commit | 26811cc9f55acf835f7fdadc5ff2bbd6f06bc3ac (patch) | |
tree | 852f49de4153d6687c91600d98d559a22c5812a3 | |
parent | 61723b393292f1e4ea27f8d123384d50b176c29d (diff) |
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: Davide Caratti <dcaratti@redhat.com>
Reviewed-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/net/tls.h | 17 | ||||
-rw-r--r-- | include/uapi/linux/inet_diag.h | 1 | ||||
-rw-r--r-- | include/uapi/linux/tls.h | 15 | ||||
-rw-r--r-- | net/tls/tls_main.c | 64 |
4 files changed, 97 insertions, 0 deletions
diff --git a/include/net/tls.h b/include/net/tls.h index 4997742475cd..ec3c3ed2c6c3 100644 --- a/include/net/tls.h +++ b/include/net/tls.h | |||
@@ -431,6 +431,23 @@ static inline bool is_tx_ready(struct tls_sw_context_tx *ctx) | |||
431 | return READ_ONCE(rec->tx_ready); | 431 | return READ_ONCE(rec->tx_ready); |
432 | } | 432 | } |
433 | 433 | ||
434 | static inline u16 tls_user_config(struct tls_context *ctx, bool tx) | ||
435 | { | ||
436 | u16 config = tx ? ctx->tx_conf : ctx->rx_conf; | ||
437 | |||
438 | switch (config) { | ||
439 | case TLS_BASE: | ||
440 | return TLS_CONF_BASE; | ||
441 | case TLS_SW: | ||
442 | return TLS_CONF_SW; | ||
443 | case TLS_HW: | ||
444 | return TLS_CONF_HW; | ||
445 | case TLS_HW_RECORD: | ||
446 | return TLS_CONF_HW_RECORD; | ||
447 | } | ||
448 | return 0; | ||
449 | } | ||
450 | |||
434 | struct sk_buff * | 451 | struct sk_buff * |
435 | tls_validate_xmit_skb(struct sock *sk, struct net_device *dev, | 452 | tls_validate_xmit_skb(struct sock *sk, struct net_device *dev, |
436 | struct sk_buff *skb); | 453 | struct sk_buff *skb); |
diff --git a/include/uapi/linux/inet_diag.h b/include/uapi/linux/inet_diag.h index e2c6273274f3..a1ff345b3f33 100644 --- a/include/uapi/linux/inet_diag.h +++ b/include/uapi/linux/inet_diag.h | |||
@@ -162,6 +162,7 @@ enum { | |||
162 | enum { | 162 | enum { |
163 | INET_ULP_INFO_UNSPEC, | 163 | INET_ULP_INFO_UNSPEC, |
164 | INET_ULP_INFO_NAME, | 164 | INET_ULP_INFO_NAME, |
165 | INET_ULP_INFO_TLS, | ||
165 | __INET_ULP_INFO_MAX, | 166 | __INET_ULP_INFO_MAX, |
166 | }; | 167 | }; |
167 | #define INET_ULP_INFO_MAX (__INET_ULP_INFO_MAX - 1) | 168 | #define INET_ULP_INFO_MAX (__INET_ULP_INFO_MAX - 1) |
diff --git a/include/uapi/linux/tls.h b/include/uapi/linux/tls.h index 5b9c26753e46..bcd2869ed472 100644 --- a/include/uapi/linux/tls.h +++ b/include/uapi/linux/tls.h | |||
@@ -109,4 +109,19 @@ struct tls12_crypto_info_aes_ccm_128 { | |||
109 | unsigned char rec_seq[TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE]; | 109 | unsigned char rec_seq[TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE]; |
110 | }; | 110 | }; |
111 | 111 | ||
112 | enum { | ||
113 | TLS_INFO_UNSPEC, | ||
114 | TLS_INFO_VERSION, | ||
115 | TLS_INFO_CIPHER, | ||
116 | TLS_INFO_TXCONF, | ||
117 | TLS_INFO_RXCONF, | ||
118 | __TLS_INFO_MAX, | ||
119 | }; | ||
120 | #define TLS_INFO_MAX (__TLS_INFO_MAX - 1) | ||
121 | |||
122 | #define TLS_CONF_BASE 1 | ||
123 | #define TLS_CONF_SW 2 | ||
124 | #define TLS_CONF_HW 3 | ||
125 | #define TLS_CONF_HW_RECORD 4 | ||
126 | |||
112 | #endif /* _UAPI_LINUX_TLS_H */ | 127 | #endif /* _UAPI_LINUX_TLS_H */ |
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index f8f2d2c3d627..277f7c209fed 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <linux/netdevice.h> | 39 | #include <linux/netdevice.h> |
40 | #include <linux/sched/signal.h> | 40 | #include <linux/sched/signal.h> |
41 | #include <linux/inetdevice.h> | 41 | #include <linux/inetdevice.h> |
42 | #include <linux/inet_diag.h> | ||
42 | 43 | ||
43 | #include <net/tls.h> | 44 | #include <net/tls.h> |
44 | 45 | ||
@@ -835,6 +836,67 @@ static void tls_update(struct sock *sk, struct proto *p) | |||
835 | } | 836 | } |
836 | } | 837 | } |
837 | 838 | ||
839 | static int tls_get_info(const struct sock *sk, struct sk_buff *skb) | ||
840 | { | ||
841 | u16 version, cipher_type; | ||
842 | struct tls_context *ctx; | ||
843 | struct nlattr *start; | ||
844 | int err; | ||
845 | |||
846 | start = nla_nest_start_noflag(skb, INET_ULP_INFO_TLS); | ||
847 | if (!start) | ||
848 | return -EMSGSIZE; | ||
849 | |||
850 | rcu_read_lock(); | ||
851 | ctx = rcu_dereference(inet_csk(sk)->icsk_ulp_data); | ||
852 | if (!ctx) { | ||
853 | err = 0; | ||
854 | goto nla_failure; | ||
855 | } | ||
856 | version = ctx->prot_info.version; | ||
857 | if (version) { | ||
858 | err = nla_put_u16(skb, TLS_INFO_VERSION, version); | ||
859 | if (err) | ||
860 | goto nla_failure; | ||
861 | } | ||
862 | cipher_type = ctx->prot_info.cipher_type; | ||
863 | if (cipher_type) { | ||
864 | err = nla_put_u16(skb, TLS_INFO_CIPHER, cipher_type); | ||
865 | if (err) | ||
866 | goto nla_failure; | ||
867 | } | ||
868 | err = nla_put_u16(skb, TLS_INFO_TXCONF, tls_user_config(ctx, true)); | ||
869 | if (err) | ||
870 | goto nla_failure; | ||
871 | |||
872 | err = nla_put_u16(skb, TLS_INFO_RXCONF, tls_user_config(ctx, false)); | ||
873 | if (err) | ||
874 | goto nla_failure; | ||
875 | |||
876 | rcu_read_unlock(); | ||
877 | nla_nest_end(skb, start); | ||
878 | return 0; | ||
879 | |||
880 | nla_failure: | ||
881 | rcu_read_unlock(); | ||
882 | nla_nest_cancel(skb, start); | ||
883 | return err; | ||
884 | } | ||
885 | |||
886 | static size_t tls_get_info_size(const struct sock *sk) | ||
887 | { | ||
888 | size_t size = 0; | ||
889 | |||
890 | size += nla_total_size(0) + /* INET_ULP_INFO_TLS */ | ||
891 | nla_total_size(sizeof(u16)) + /* TLS_INFO_VERSION */ | ||
892 | nla_total_size(sizeof(u16)) + /* TLS_INFO_CIPHER */ | ||
893 | nla_total_size(sizeof(u16)) + /* TLS_INFO_RXCONF */ | ||
894 | nla_total_size(sizeof(u16)) + /* TLS_INFO_TXCONF */ | ||
895 | 0; | ||
896 | |||
897 | return size; | ||
898 | } | ||
899 | |||
838 | void tls_register_device(struct tls_device *device) | 900 | void tls_register_device(struct tls_device *device) |
839 | { | 901 | { |
840 | spin_lock_bh(&device_spinlock); | 902 | spin_lock_bh(&device_spinlock); |
@@ -856,6 +918,8 @@ static struct tcp_ulp_ops tcp_tls_ulp_ops __read_mostly = { | |||
856 | .owner = THIS_MODULE, | 918 | .owner = THIS_MODULE, |
857 | .init = tls_init, | 919 | .init = tls_init, |
858 | .update = tls_update, | 920 | .update = tls_update, |
921 | .get_info = tls_get_info, | ||
922 | .get_info_size = tls_get_info_size, | ||
859 | }; | 923 | }; |
860 | 924 | ||
861 | static int __init tls_register(void) | 925 | static int __init tls_register(void) |