mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
tls: remove tls_toe and the related driver
The tls_toe feature and its single user (chelsio chtls) have been unmaintained for multiple years. It also hooks into the core of the TCP implementation, and bypasses most of the networking stack. Signed-off-by: Sabrina Dubroca <sd@queasysnail.net> Reviewed-by: Eric Dumazet <edumazet@google.com> Link: https://patch.msgid.link/1f30e73275c07bf879f547589872d0916025a52e.1781165969.git.sd@queasysnail.net Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
f48cd5b47b
commit
cdae65fc43
@@ -13,7 +13,7 @@ Layer Protocol (ULP) and install the cryptographic connection state.
|
||||
For details regarding the user-facing interface refer to the TLS
|
||||
documentation in :ref:`Documentation/networking/tls.rst <kernel_tls>`.
|
||||
|
||||
``ktls`` can operate in three modes:
|
||||
``ktls`` can operate in two modes:
|
||||
|
||||
* Software crypto mode (``TLS_SW``) - CPU handles the cryptography.
|
||||
In most basic cases only crypto operations synchronous with the CPU
|
||||
@@ -26,11 +26,6 @@ documentation in :ref:`Documentation/networking/tls.rst <kernel_tls>`.
|
||||
This mode integrates best with the kernel stack and is described in detail
|
||||
in the remaining part of this document
|
||||
(``ethtool`` flags ``tls-hw-tx-offload`` and ``tls-hw-rx-offload``).
|
||||
* Full TCP NIC offload mode (``TLS_HW_RECORD``) - mode of operation where
|
||||
NIC driver and firmware replace the kernel networking stack
|
||||
with its own TCP handling, it is not usable in production environments
|
||||
making use of the Linux networking stack for example any firewalling
|
||||
abilities or QoS and packet scheduling (``ethtool`` flag ``tls-hw-record``).
|
||||
|
||||
The operation mode is selected automatically based on device configuration,
|
||||
offload opt-in or opt-out on per-connection basis is not currently supported.
|
||||
|
||||
@@ -125,7 +125,6 @@ CONFIG_UNIX=y
|
||||
CONFIG_UNIX_DIAG=m
|
||||
CONFIG_TLS=m
|
||||
CONFIG_TLS_DEVICE=y
|
||||
CONFIG_TLS_TOE=y
|
||||
CONFIG_XFRM_USER=m
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_SMC=m
|
||||
|
||||
@@ -116,7 +116,6 @@ CONFIG_UNIX=y
|
||||
CONFIG_UNIX_DIAG=m
|
||||
CONFIG_TLS=m
|
||||
CONFIG_TLS_DEVICE=y
|
||||
CONFIG_TLS_TOE=y
|
||||
CONFIG_XFRM_USER=m
|
||||
CONFIG_NET_KEY=m
|
||||
CONFIG_SMC=m
|
||||
|
||||
@@ -6795,8 +6795,7 @@ static int init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
NETIF_F_TSO | NETIF_F_TSO6;
|
||||
|
||||
netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL |
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM |
|
||||
NETIF_F_HW_TLS_RECORD;
|
||||
NETIF_F_GSO_UDP_TUNNEL_CSUM;
|
||||
|
||||
if (adapter->rawf_cnt)
|
||||
netdev->udp_tunnel_nic_info = &cxgb_udp_tunnels;
|
||||
|
||||
@@ -13,18 +13,6 @@ config CHELSIO_INLINE_CRYPTO
|
||||
|
||||
if CHELSIO_INLINE_CRYPTO
|
||||
|
||||
config CRYPTO_DEV_CHELSIO_TLS
|
||||
tristate "Chelsio Crypto Inline TLS Driver"
|
||||
depends on CHELSIO_T4
|
||||
depends on TLS
|
||||
depends on TLS_TOE
|
||||
help
|
||||
Support Chelsio Inline TLS with Chelsio crypto accelerator.
|
||||
Enable inline TLS support for Tx and Rx.
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called chtls.
|
||||
|
||||
config CHELSIO_IPSEC_INLINE
|
||||
tristate "Chelsio IPSec XFRM Tx crypto offload"
|
||||
depends on CHELSIO_T4
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_CRYPTO_DEV_CHELSIO_TLS) += chtls/
|
||||
obj-$(CONFIG_CHELSIO_IPSEC_INLINE) += ch_ipsec/
|
||||
obj-$(CONFIG_CHELSIO_TLS_DEVICE) += ch_ktls/
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
ccflags-y := -I $(srctree)/drivers/net/ethernet/chelsio/cxgb4 \
|
||||
-I $(srctree)/drivers/crypto/chelsio
|
||||
|
||||
obj-$(CONFIG_CRYPTO_DEV_CHELSIO_TLS) += chtls.o
|
||||
chtls-objs := chtls_main.o chtls_cm.o chtls_io.o chtls_hw.o
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,218 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2018 Chelsio Communications, Inc.
|
||||
*/
|
||||
|
||||
#ifndef __CHTLS_CM_H__
|
||||
#define __CHTLS_CM_H__
|
||||
|
||||
/*
|
||||
* TCB settings
|
||||
*/
|
||||
/* 3:0 */
|
||||
#define TCB_ULP_TYPE_W 0
|
||||
#define TCB_ULP_TYPE_S 0
|
||||
#define TCB_ULP_TYPE_M 0xfULL
|
||||
#define TCB_ULP_TYPE_V(x) ((x) << TCB_ULP_TYPE_S)
|
||||
|
||||
/* 11:4 */
|
||||
#define TCB_ULP_RAW_W 0
|
||||
#define TCB_ULP_RAW_S 4
|
||||
#define TCB_ULP_RAW_M 0xffULL
|
||||
#define TCB_ULP_RAW_V(x) ((x) << TCB_ULP_RAW_S)
|
||||
|
||||
#define TF_TLS_KEY_SIZE_S 7
|
||||
#define TF_TLS_KEY_SIZE_V(x) ((x) << TF_TLS_KEY_SIZE_S)
|
||||
|
||||
#define TF_TLS_CONTROL_S 2
|
||||
#define TF_TLS_CONTROL_V(x) ((x) << TF_TLS_CONTROL_S)
|
||||
|
||||
#define TF_TLS_ACTIVE_S 1
|
||||
#define TF_TLS_ACTIVE_V(x) ((x) << TF_TLS_ACTIVE_S)
|
||||
|
||||
#define TF_TLS_ENABLE_S 0
|
||||
#define TF_TLS_ENABLE_V(x) ((x) << TF_TLS_ENABLE_S)
|
||||
|
||||
#define TF_RX_QUIESCE_S 15
|
||||
#define TF_RX_QUIESCE_V(x) ((x) << TF_RX_QUIESCE_S)
|
||||
|
||||
/*
|
||||
* Max receive window supported by HW in bytes. Only a small part of it can
|
||||
* be set through option0, the rest needs to be set through RX_DATA_ACK.
|
||||
*/
|
||||
#define MAX_RCV_WND ((1U << 27) - 1)
|
||||
#define MAX_MSS 65536
|
||||
|
||||
/*
|
||||
* Min receive window. We want it to be large enough to accommodate receive
|
||||
* coalescing, handle jumbo frames, and not trigger sender SWS avoidance.
|
||||
*/
|
||||
#define MIN_RCV_WND (24 * 1024U)
|
||||
#define LOOPBACK(x) (((x) & htonl(0xff000000)) == htonl(0x7f000000))
|
||||
|
||||
/* for TX: a skb must have a headroom of at least TX_HEADER_LEN bytes */
|
||||
#define TX_HEADER_LEN \
|
||||
(sizeof(struct fw_ofld_tx_data_wr) + sizeof(struct sge_opaque_hdr))
|
||||
#define TX_TLSHDR_LEN \
|
||||
(sizeof(struct fw_tlstx_data_wr) + sizeof(struct cpl_tx_tls_sfo) + \
|
||||
sizeof(struct sge_opaque_hdr))
|
||||
#define TXDATA_SKB_LEN 128
|
||||
|
||||
enum {
|
||||
CPL_TX_TLS_SFO_TYPE_CCS,
|
||||
CPL_TX_TLS_SFO_TYPE_ALERT,
|
||||
CPL_TX_TLS_SFO_TYPE_HANDSHAKE,
|
||||
CPL_TX_TLS_SFO_TYPE_DATA,
|
||||
CPL_TX_TLS_SFO_TYPE_HEARTBEAT,
|
||||
};
|
||||
|
||||
enum {
|
||||
TLS_HDR_TYPE_CCS = 20,
|
||||
TLS_HDR_TYPE_ALERT,
|
||||
TLS_HDR_TYPE_HANDSHAKE,
|
||||
TLS_HDR_TYPE_RECORD,
|
||||
TLS_HDR_TYPE_HEARTBEAT,
|
||||
};
|
||||
|
||||
typedef void (*defer_handler_t)(struct chtls_dev *dev, struct sk_buff *skb);
|
||||
extern struct request_sock_ops chtls_rsk_ops;
|
||||
extern struct request_sock_ops chtls_rsk_opsv6;
|
||||
|
||||
struct deferred_skb_cb {
|
||||
defer_handler_t handler;
|
||||
struct chtls_dev *dev;
|
||||
};
|
||||
|
||||
#define DEFERRED_SKB_CB(skb) ((struct deferred_skb_cb *)(skb)->cb)
|
||||
#define failover_flowc_wr_len offsetof(struct fw_flowc_wr, mnemval[3])
|
||||
#define WR_SKB_CB(skb) ((struct wr_skb_cb *)(skb)->cb)
|
||||
#define ACCEPT_QUEUE(sk) (&inet_csk(sk)->icsk_accept_queue.rskq_accept_head)
|
||||
|
||||
#define SND_WSCALE(tp) ((tp)->rx_opt.snd_wscale)
|
||||
#define RCV_WSCALE(tp) ((tp)->rx_opt.rcv_wscale)
|
||||
#define USER_MSS(tp) (READ_ONCE((tp)->rx_opt.user_mss))
|
||||
#define TS_RECENT_STAMP(tp) ((tp)->rx_opt.ts_recent_stamp)
|
||||
#define WSCALE_OK(tp) ((tp)->rx_opt.wscale_ok)
|
||||
#define TSTAMP_OK(tp) ((tp)->rx_opt.tstamp_ok)
|
||||
#define SACK_OK(tp) ((tp)->rx_opt.sack_ok)
|
||||
|
||||
/* TLS SKB */
|
||||
#define skb_ulp_tls_inline(skb) (ULP_SKB_CB(skb)->ulp.tls.ofld)
|
||||
#define skb_ulp_tls_iv_imm(skb) (ULP_SKB_CB(skb)->ulp.tls.iv)
|
||||
|
||||
void chtls_defer_reply(struct sk_buff *skb, struct chtls_dev *dev,
|
||||
defer_handler_t handler);
|
||||
|
||||
/*
|
||||
* Returns true if the socket is in one of the supplied states.
|
||||
*/
|
||||
static inline unsigned int sk_in_state(const struct sock *sk,
|
||||
unsigned int states)
|
||||
{
|
||||
return states & (1 << sk->sk_state);
|
||||
}
|
||||
|
||||
static void chtls_rsk_destructor(struct request_sock *req)
|
||||
{
|
||||
/* do nothing */
|
||||
}
|
||||
|
||||
static inline void chtls_init_rsk_ops(struct proto *chtls_tcp_prot,
|
||||
struct request_sock_ops *chtls_tcp_ops,
|
||||
struct proto *tcp_prot, int family)
|
||||
{
|
||||
memset(chtls_tcp_ops, 0, sizeof(*chtls_tcp_ops));
|
||||
chtls_tcp_ops->family = family;
|
||||
chtls_tcp_ops->obj_size = sizeof(struct tcp_request_sock);
|
||||
chtls_tcp_ops->destructor = chtls_rsk_destructor;
|
||||
chtls_tcp_ops->slab = tcp_prot->rsk_prot->slab;
|
||||
chtls_tcp_prot->rsk_prot = chtls_tcp_ops;
|
||||
}
|
||||
|
||||
static inline void chtls_reqsk_free(struct request_sock *req)
|
||||
{
|
||||
if (req->rsk_listener)
|
||||
sock_put(req->rsk_listener);
|
||||
kmem_cache_free(req->rsk_ops->slab, req);
|
||||
}
|
||||
|
||||
#define DECLARE_TASK_FUNC(task, task_param) \
|
||||
static void task(struct work_struct *task_param)
|
||||
|
||||
static inline void sk_wakeup_sleepers(struct sock *sk, bool interruptable)
|
||||
{
|
||||
struct socket_wq *wq;
|
||||
|
||||
rcu_read_lock();
|
||||
wq = rcu_dereference(sk->sk_wq);
|
||||
if (skwq_has_sleeper(wq)) {
|
||||
if (interruptable)
|
||||
wake_up_interruptible(sk_sleep(sk));
|
||||
else
|
||||
wake_up_all(sk_sleep(sk));
|
||||
}
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static inline void chtls_set_req_port(struct request_sock *oreq,
|
||||
__be16 source, __be16 dest)
|
||||
{
|
||||
inet_rsk(oreq)->ir_rmt_port = source;
|
||||
inet_rsk(oreq)->ir_num = ntohs(dest);
|
||||
}
|
||||
|
||||
static inline void chtls_set_req_addr(struct request_sock *oreq,
|
||||
__be32 local_ip, __be32 peer_ip)
|
||||
{
|
||||
inet_rsk(oreq)->ir_loc_addr = local_ip;
|
||||
inet_rsk(oreq)->ir_rmt_addr = peer_ip;
|
||||
}
|
||||
|
||||
static inline void chtls_free_skb(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
skb_dstref_steal(skb);
|
||||
__skb_unlink(skb, &sk->sk_receive_queue);
|
||||
__kfree_skb(skb);
|
||||
}
|
||||
|
||||
static inline void chtls_kfree_skb(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
skb_dstref_steal(skb);
|
||||
__skb_unlink(skb, &sk->sk_receive_queue);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
static inline void chtls_reset_wr_list(struct chtls_sock *csk)
|
||||
{
|
||||
csk->wr_skb_head = NULL;
|
||||
csk->wr_skb_tail = NULL;
|
||||
}
|
||||
|
||||
static inline void enqueue_wr(struct chtls_sock *csk, struct sk_buff *skb)
|
||||
{
|
||||
WR_SKB_CB(skb)->next_wr = NULL;
|
||||
|
||||
skb_get(skb);
|
||||
|
||||
if (!csk->wr_skb_head)
|
||||
csk->wr_skb_head = skb;
|
||||
else
|
||||
WR_SKB_CB(csk->wr_skb_tail)->next_wr = skb;
|
||||
csk->wr_skb_tail = skb;
|
||||
}
|
||||
|
||||
static inline struct sk_buff *dequeue_wr(struct sock *sk)
|
||||
{
|
||||
struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
|
||||
struct sk_buff *skb = NULL;
|
||||
|
||||
skb = csk->wr_skb_head;
|
||||
|
||||
if (likely(skb)) {
|
||||
/* Don't bother clearing the tail */
|
||||
csk->wr_skb_head = WR_SKB_CB(skb)->next_wr;
|
||||
WR_SKB_CB(skb)->next_wr = NULL;
|
||||
}
|
||||
return skb;
|
||||
}
|
||||
#endif
|
||||
@@ -1,462 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018 Chelsio Communications, Inc.
|
||||
*
|
||||
* Written by: Atul Gupta (atul.gupta@chelsio.com)
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/inetdevice.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/tls.h>
|
||||
#include <net/tls.h>
|
||||
|
||||
#include "chtls.h"
|
||||
#include "chtls_cm.h"
|
||||
|
||||
static void __set_tcb_field_direct(struct chtls_sock *csk,
|
||||
struct cpl_set_tcb_field *req, u16 word,
|
||||
u64 mask, u64 val, u8 cookie, int no_reply)
|
||||
{
|
||||
struct ulptx_idata *sc;
|
||||
|
||||
INIT_TP_WR_CPL(req, CPL_SET_TCB_FIELD, csk->tid);
|
||||
req->wr.wr_mid |= htonl(FW_WR_FLOWID_V(csk->tid));
|
||||
req->reply_ctrl = htons(NO_REPLY_V(no_reply) |
|
||||
QUEUENO_V(csk->rss_qid));
|
||||
req->word_cookie = htons(TCB_WORD_V(word) | TCB_COOKIE_V(cookie));
|
||||
req->mask = cpu_to_be64(mask);
|
||||
req->val = cpu_to_be64(val);
|
||||
sc = (struct ulptx_idata *)(req + 1);
|
||||
sc->cmd_more = htonl(ULPTX_CMD_V(ULP_TX_SC_NOOP));
|
||||
sc->len = htonl(0);
|
||||
}
|
||||
|
||||
static void __set_tcb_field(struct sock *sk, struct sk_buff *skb, u16 word,
|
||||
u64 mask, u64 val, u8 cookie, int no_reply)
|
||||
{
|
||||
struct cpl_set_tcb_field *req;
|
||||
struct chtls_sock *csk;
|
||||
struct ulptx_idata *sc;
|
||||
unsigned int wrlen;
|
||||
|
||||
wrlen = roundup(sizeof(*req) + sizeof(*sc), 16);
|
||||
csk = rcu_dereference_sk_user_data(sk);
|
||||
|
||||
req = (struct cpl_set_tcb_field *)__skb_put(skb, wrlen);
|
||||
__set_tcb_field_direct(csk, req, word, mask, val, cookie, no_reply);
|
||||
set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send control message to HW, message go as immediate data and packet
|
||||
* is freed immediately.
|
||||
*/
|
||||
static int chtls_set_tcb_field(struct sock *sk, u16 word, u64 mask, u64 val)
|
||||
{
|
||||
struct cpl_set_tcb_field *req;
|
||||
unsigned int credits_needed;
|
||||
struct chtls_sock *csk;
|
||||
struct ulptx_idata *sc;
|
||||
struct sk_buff *skb;
|
||||
unsigned int wrlen;
|
||||
int ret;
|
||||
|
||||
wrlen = roundup(sizeof(*req) + sizeof(*sc), 16);
|
||||
|
||||
skb = alloc_skb(wrlen, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
credits_needed = DIV_ROUND_UP(wrlen, 16);
|
||||
csk = rcu_dereference_sk_user_data(sk);
|
||||
|
||||
__set_tcb_field(sk, skb, word, mask, val, 0, 1);
|
||||
skb_set_queue_mapping(skb, (csk->txq_idx << 1) | CPL_PRIORITY_DATA);
|
||||
csk->wr_credits -= credits_needed;
|
||||
csk->wr_unacked += credits_needed;
|
||||
enqueue_wr(csk, skb);
|
||||
ret = cxgb4_ofld_send(csk->egress_dev, skb);
|
||||
if (ret < 0)
|
||||
kfree_skb(skb);
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
void chtls_set_tcb_field_rpl_skb(struct sock *sk, u16 word,
|
||||
u64 mask, u64 val, u8 cookie,
|
||||
int through_l2t)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
unsigned int wrlen;
|
||||
|
||||
wrlen = sizeof(struct cpl_set_tcb_field) + sizeof(struct ulptx_idata);
|
||||
wrlen = roundup(wrlen, 16);
|
||||
|
||||
skb = alloc_skb(wrlen, GFP_KERNEL | __GFP_NOFAIL);
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
__set_tcb_field(sk, skb, word, mask, val, cookie, 0);
|
||||
send_or_defer(sk, tcp_sk(sk), skb, through_l2t);
|
||||
}
|
||||
|
||||
static int chtls_set_tcb_keyid(struct sock *sk, int keyid)
|
||||
{
|
||||
return chtls_set_tcb_field(sk, 31, 0xFFFFFFFFULL, keyid);
|
||||
}
|
||||
|
||||
static int chtls_set_tcb_seqno(struct sock *sk)
|
||||
{
|
||||
return chtls_set_tcb_field(sk, 28, ~0ULL, 0);
|
||||
}
|
||||
|
||||
static int chtls_set_tcb_quiesce(struct sock *sk, int val)
|
||||
{
|
||||
return chtls_set_tcb_field(sk, 1, (1ULL << TF_RX_QUIESCE_S),
|
||||
TF_RX_QUIESCE_V(val));
|
||||
}
|
||||
|
||||
void chtls_set_quiesce_ctrl(struct sock *sk, int val)
|
||||
{
|
||||
struct chtls_sock *csk;
|
||||
struct sk_buff *skb;
|
||||
unsigned int wrlen;
|
||||
int ret;
|
||||
|
||||
wrlen = sizeof(struct cpl_set_tcb_field) + sizeof(struct ulptx_idata);
|
||||
wrlen = roundup(wrlen, 16);
|
||||
|
||||
skb = alloc_skb(wrlen, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
return;
|
||||
|
||||
csk = rcu_dereference_sk_user_data(sk);
|
||||
|
||||
__set_tcb_field(sk, skb, 1, TF_RX_QUIESCE_V(1), 0, 0, 1);
|
||||
set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id);
|
||||
ret = cxgb4_ofld_send(csk->egress_dev, skb);
|
||||
if (ret < 0)
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
/* TLS Key bitmap processing */
|
||||
int chtls_init_kmap(struct chtls_dev *cdev, struct cxgb4_lld_info *lldi)
|
||||
{
|
||||
unsigned int num_key_ctx, bsize;
|
||||
int ksize;
|
||||
|
||||
num_key_ctx = (lldi->vr->key.size / TLS_KEY_CONTEXT_SZ);
|
||||
bsize = BITS_TO_LONGS(num_key_ctx);
|
||||
|
||||
cdev->kmap.size = num_key_ctx;
|
||||
cdev->kmap.available = bsize;
|
||||
ksize = sizeof(*cdev->kmap.addr) * bsize;
|
||||
cdev->kmap.addr = kvzalloc(ksize, GFP_KERNEL);
|
||||
if (!cdev->kmap.addr)
|
||||
return -ENOMEM;
|
||||
|
||||
cdev->kmap.start = lldi->vr->key.start;
|
||||
spin_lock_init(&cdev->kmap.lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_new_keyid(struct chtls_sock *csk, u32 optname)
|
||||
{
|
||||
struct net_device *dev = csk->egress_dev;
|
||||
struct chtls_dev *cdev = csk->cdev;
|
||||
struct chtls_hws *hws;
|
||||
struct adapter *adap;
|
||||
int keyid;
|
||||
|
||||
adap = netdev2adap(dev);
|
||||
hws = &csk->tlshws;
|
||||
|
||||
spin_lock_bh(&cdev->kmap.lock);
|
||||
keyid = find_first_zero_bit(cdev->kmap.addr, cdev->kmap.size);
|
||||
if (keyid < cdev->kmap.size) {
|
||||
__set_bit(keyid, cdev->kmap.addr);
|
||||
if (optname == TLS_RX)
|
||||
hws->rxkey = keyid;
|
||||
else
|
||||
hws->txkey = keyid;
|
||||
atomic_inc(&adap->chcr_stats.tls_key);
|
||||
} else {
|
||||
keyid = -1;
|
||||
}
|
||||
spin_unlock_bh(&cdev->kmap.lock);
|
||||
return keyid;
|
||||
}
|
||||
|
||||
void free_tls_keyid(struct sock *sk)
|
||||
{
|
||||
struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
|
||||
struct net_device *dev = csk->egress_dev;
|
||||
struct chtls_dev *cdev = csk->cdev;
|
||||
struct chtls_hws *hws;
|
||||
struct adapter *adap;
|
||||
|
||||
if (!cdev->kmap.addr)
|
||||
return;
|
||||
|
||||
adap = netdev2adap(dev);
|
||||
hws = &csk->tlshws;
|
||||
|
||||
spin_lock_bh(&cdev->kmap.lock);
|
||||
if (hws->rxkey >= 0) {
|
||||
__clear_bit(hws->rxkey, cdev->kmap.addr);
|
||||
atomic_dec(&adap->chcr_stats.tls_key);
|
||||
hws->rxkey = -1;
|
||||
}
|
||||
if (hws->txkey >= 0) {
|
||||
__clear_bit(hws->txkey, cdev->kmap.addr);
|
||||
atomic_dec(&adap->chcr_stats.tls_key);
|
||||
hws->txkey = -1;
|
||||
}
|
||||
spin_unlock_bh(&cdev->kmap.lock);
|
||||
}
|
||||
|
||||
unsigned int keyid_to_addr(int start_addr, int keyid)
|
||||
{
|
||||
return (start_addr + (keyid * TLS_KEY_CONTEXT_SZ)) >> 5;
|
||||
}
|
||||
|
||||
static void chtls_rxkey_ivauth(struct _key_ctx *kctx)
|
||||
{
|
||||
kctx->iv_to_auth = cpu_to_be64(KEYCTX_TX_WR_IV_V(6ULL) |
|
||||
KEYCTX_TX_WR_AAD_V(1ULL) |
|
||||
KEYCTX_TX_WR_AADST_V(5ULL) |
|
||||
KEYCTX_TX_WR_CIPHER_V(14ULL) |
|
||||
KEYCTX_TX_WR_CIPHERST_V(0ULL) |
|
||||
KEYCTX_TX_WR_AUTH_V(14ULL) |
|
||||
KEYCTX_TX_WR_AUTHST_V(16ULL) |
|
||||
KEYCTX_TX_WR_AUTHIN_V(16ULL));
|
||||
}
|
||||
|
||||
static int chtls_key_info(struct chtls_sock *csk,
|
||||
struct _key_ctx *kctx,
|
||||
u32 keylen, u32 optname,
|
||||
int cipher_type)
|
||||
{
|
||||
unsigned char key[AES_MAX_KEY_SIZE];
|
||||
unsigned char *key_p, *salt;
|
||||
unsigned char ghash_h[AEAD_H_SIZE];
|
||||
int ck_size, key_ctx_size, kctx_mackey_size, salt_size;
|
||||
struct aes_enckey aes;
|
||||
int ret;
|
||||
|
||||
key_ctx_size = sizeof(struct _key_ctx) +
|
||||
roundup(keylen, 16) + AEAD_H_SIZE;
|
||||
|
||||
/* GCM mode of AES supports 128 and 256 bit encryption, so
|
||||
* prepare key context base on GCM cipher type
|
||||
*/
|
||||
switch (cipher_type) {
|
||||
case TLS_CIPHER_AES_GCM_128: {
|
||||
struct tls12_crypto_info_aes_gcm_128 *gcm_ctx_128 =
|
||||
(struct tls12_crypto_info_aes_gcm_128 *)
|
||||
&csk->tlshws.crypto_info;
|
||||
memcpy(key, gcm_ctx_128->key, keylen);
|
||||
|
||||
key_p = gcm_ctx_128->key;
|
||||
salt = gcm_ctx_128->salt;
|
||||
ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_128;
|
||||
salt_size = TLS_CIPHER_AES_GCM_128_SALT_SIZE;
|
||||
kctx_mackey_size = CHCR_KEYCTX_MAC_KEY_SIZE_128;
|
||||
break;
|
||||
}
|
||||
case TLS_CIPHER_AES_GCM_256: {
|
||||
struct tls12_crypto_info_aes_gcm_256 *gcm_ctx_256 =
|
||||
(struct tls12_crypto_info_aes_gcm_256 *)
|
||||
&csk->tlshws.crypto_info;
|
||||
memcpy(key, gcm_ctx_256->key, keylen);
|
||||
|
||||
key_p = gcm_ctx_256->key;
|
||||
salt = gcm_ctx_256->salt;
|
||||
ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_256;
|
||||
salt_size = TLS_CIPHER_AES_GCM_256_SALT_SIZE;
|
||||
kctx_mackey_size = CHCR_KEYCTX_MAC_KEY_SIZE_256;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
pr_err("GCM: Invalid key length %d\n", keylen);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Calculate the H = CIPH(K, 0 repeated 16 times).
|
||||
* It will go in key context
|
||||
*/
|
||||
ret = aes_prepareenckey(&aes, key, keylen);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memset(ghash_h, 0, AEAD_H_SIZE);
|
||||
aes_encrypt(&aes, ghash_h, ghash_h);
|
||||
memzero_explicit(&aes, sizeof(aes));
|
||||
csk->tlshws.keylen = key_ctx_size;
|
||||
|
||||
/* Copy the Key context */
|
||||
if (optname == TLS_RX) {
|
||||
int key_ctx;
|
||||
|
||||
key_ctx = ((key_ctx_size >> 4) << 3);
|
||||
kctx->ctx_hdr = FILL_KEY_CRX_HDR(ck_size,
|
||||
kctx_mackey_size,
|
||||
0, 0, key_ctx);
|
||||
chtls_rxkey_ivauth(kctx);
|
||||
} else {
|
||||
kctx->ctx_hdr = FILL_KEY_CTX_HDR(ck_size,
|
||||
kctx_mackey_size,
|
||||
0, 0, key_ctx_size >> 4);
|
||||
}
|
||||
|
||||
memcpy(kctx->salt, salt, salt_size);
|
||||
memcpy(kctx->key, key_p, keylen);
|
||||
memcpy(kctx->key + keylen, ghash_h, AEAD_H_SIZE);
|
||||
/* erase key info from driver */
|
||||
memset(key_p, 0, keylen);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void chtls_set_scmd(struct chtls_sock *csk)
|
||||
{
|
||||
struct chtls_hws *hws = &csk->tlshws;
|
||||
|
||||
hws->scmd.seqno_numivs =
|
||||
SCMD_SEQ_NO_CTRL_V(3) |
|
||||
SCMD_PROTO_VERSION_V(0) |
|
||||
SCMD_ENC_DEC_CTRL_V(0) |
|
||||
SCMD_CIPH_AUTH_SEQ_CTRL_V(1) |
|
||||
SCMD_CIPH_MODE_V(2) |
|
||||
SCMD_AUTH_MODE_V(4) |
|
||||
SCMD_HMAC_CTRL_V(0) |
|
||||
SCMD_IV_SIZE_V(4) |
|
||||
SCMD_NUM_IVS_V(1);
|
||||
|
||||
hws->scmd.ivgen_hdrlen =
|
||||
SCMD_IV_GEN_CTRL_V(1) |
|
||||
SCMD_KEY_CTX_INLINE_V(0) |
|
||||
SCMD_TLS_FRAG_ENABLE_V(1);
|
||||
}
|
||||
|
||||
int chtls_setkey(struct chtls_sock *csk, u32 keylen,
|
||||
u32 optname, int cipher_type)
|
||||
{
|
||||
struct tls_key_req *kwr;
|
||||
struct chtls_dev *cdev;
|
||||
struct _key_ctx *kctx;
|
||||
int wrlen, klen, len;
|
||||
struct sk_buff *skb;
|
||||
struct sock *sk;
|
||||
int keyid;
|
||||
int kaddr;
|
||||
int ret;
|
||||
|
||||
cdev = csk->cdev;
|
||||
sk = csk->sk;
|
||||
|
||||
klen = roundup((keylen + AEAD_H_SIZE) + sizeof(*kctx), 32);
|
||||
wrlen = roundup(sizeof(*kwr), 16);
|
||||
len = klen + wrlen;
|
||||
|
||||
/* Flush out-standing data before new key takes effect */
|
||||
if (optname == TLS_TX) {
|
||||
lock_sock(sk);
|
||||
if (skb_queue_len(&csk->txq))
|
||||
chtls_push_frames(csk, 0);
|
||||
release_sock(sk);
|
||||
}
|
||||
|
||||
skb = alloc_skb(len, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
keyid = get_new_keyid(csk, optname);
|
||||
if (keyid < 0) {
|
||||
ret = -ENOSPC;
|
||||
goto out_nokey;
|
||||
}
|
||||
|
||||
kaddr = keyid_to_addr(cdev->kmap.start, keyid);
|
||||
kwr = (struct tls_key_req *)__skb_put_zero(skb, len);
|
||||
kwr->wr.op_to_compl =
|
||||
cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR) | FW_WR_COMPL_F |
|
||||
FW_WR_ATOMIC_V(1U));
|
||||
kwr->wr.flowid_len16 =
|
||||
cpu_to_be32(FW_WR_LEN16_V(DIV_ROUND_UP(len, 16) |
|
||||
FW_WR_FLOWID_V(csk->tid)));
|
||||
kwr->wr.protocol = 0;
|
||||
kwr->wr.mfs = htons(TLS_MFS);
|
||||
kwr->wr.reneg_to_write_rx = optname;
|
||||
|
||||
/* ulptx command */
|
||||
kwr->req.cmd = cpu_to_be32(ULPTX_CMD_V(ULP_TX_MEM_WRITE) |
|
||||
T5_ULP_MEMIO_ORDER_V(1) |
|
||||
T5_ULP_MEMIO_IMM_V(1));
|
||||
kwr->req.len16 = cpu_to_be32((csk->tid << 8) |
|
||||
DIV_ROUND_UP(len - sizeof(kwr->wr), 16));
|
||||
kwr->req.dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN_V(klen >> 5));
|
||||
kwr->req.lock_addr = cpu_to_be32(ULP_MEMIO_ADDR_V(kaddr));
|
||||
|
||||
/* sub command */
|
||||
kwr->sc_imm.cmd_more = cpu_to_be32(ULPTX_CMD_V(ULP_TX_SC_IMM));
|
||||
kwr->sc_imm.len = cpu_to_be32(klen);
|
||||
|
||||
lock_sock(sk);
|
||||
/* key info */
|
||||
kctx = (struct _key_ctx *)(kwr + 1);
|
||||
ret = chtls_key_info(csk, kctx, keylen, optname, cipher_type);
|
||||
if (ret)
|
||||
goto out_notcb;
|
||||
|
||||
if (unlikely(csk_flag(sk, CSK_ABORT_SHUTDOWN)))
|
||||
goto out_notcb;
|
||||
|
||||
set_wr_txq(skb, CPL_PRIORITY_DATA, csk->tlshws.txqid);
|
||||
csk->wr_credits -= DIV_ROUND_UP(len, 16);
|
||||
csk->wr_unacked += DIV_ROUND_UP(len, 16);
|
||||
enqueue_wr(csk, skb);
|
||||
cxgb4_ofld_send(csk->egress_dev, skb);
|
||||
skb = NULL;
|
||||
|
||||
chtls_set_scmd(csk);
|
||||
/* Clear quiesce for Rx key */
|
||||
if (optname == TLS_RX) {
|
||||
ret = chtls_set_tcb_keyid(sk, keyid);
|
||||
if (ret)
|
||||
goto out_notcb;
|
||||
ret = chtls_set_tcb_field(sk, 0,
|
||||
TCB_ULP_RAW_V(TCB_ULP_RAW_M),
|
||||
TCB_ULP_RAW_V((TF_TLS_KEY_SIZE_V(1) |
|
||||
TF_TLS_CONTROL_V(1) |
|
||||
TF_TLS_ACTIVE_V(1) |
|
||||
TF_TLS_ENABLE_V(1))));
|
||||
if (ret)
|
||||
goto out_notcb;
|
||||
ret = chtls_set_tcb_seqno(sk);
|
||||
if (ret)
|
||||
goto out_notcb;
|
||||
ret = chtls_set_tcb_quiesce(sk, 0);
|
||||
if (ret)
|
||||
goto out_notcb;
|
||||
csk->tlshws.rxkey = keyid;
|
||||
} else {
|
||||
csk->tlshws.tx_seq_no = 0;
|
||||
csk->tlshws.txkey = keyid;
|
||||
}
|
||||
|
||||
release_sock(sk);
|
||||
return ret;
|
||||
out_notcb:
|
||||
release_sock(sk);
|
||||
free_tls_keyid(sk);
|
||||
out_nokey:
|
||||
kfree_skb(skb);
|
||||
return ret;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -79,7 +79,7 @@ enum {
|
||||
NETIF_F_HW_TLS_RX_BIT, /* Hardware TLS RX offload */
|
||||
|
||||
NETIF_F_GRO_HW_BIT, /* Hardware Generic receive offload */
|
||||
NETIF_F_HW_TLS_RECORD_BIT, /* Offload TLS record */
|
||||
__UNUSED_NETIF_F_56,
|
||||
NETIF_F_GRO_FRAGLIST_BIT, /* Fraglist GRO */
|
||||
|
||||
NETIF_F_HW_MACSEC_BIT, /* Offload MACsec operations */
|
||||
@@ -153,7 +153,6 @@ enum {
|
||||
#define NETIF_F_HW_ESP __NETIF_F(HW_ESP)
|
||||
#define NETIF_F_HW_ESP_TX_CSUM __NETIF_F(HW_ESP_TX_CSUM)
|
||||
#define NETIF_F_RX_UDP_TUNNEL_PORT __NETIF_F(RX_UDP_TUNNEL_PORT)
|
||||
#define NETIF_F_HW_TLS_RECORD __NETIF_F(HW_TLS_RECORD)
|
||||
#define NETIF_F_GSO_UDP_L4 __NETIF_F(GSO_UDP_L4)
|
||||
#define NETIF_F_HW_TLS_TX __NETIF_F(HW_TLS_TX)
|
||||
#define NETIF_F_HW_TLS_RX __NETIF_F(HW_TLS_RX)
|
||||
|
||||
@@ -85,7 +85,6 @@ enum {
|
||||
TLS_BASE,
|
||||
TLS_SW,
|
||||
TLS_HW,
|
||||
TLS_HW_RECORD,
|
||||
TLS_NUM_CONFIG,
|
||||
};
|
||||
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved.
|
||||
* Copyright (c) 2016-2017, Dave Watson <davejwatson@fb.com>. All rights reserved.
|
||||
*
|
||||
* This software is available to you under a choice of one of two
|
||||
* licenses. You may choose to be licensed under the terms of the GNU
|
||||
* General Public License (GPL) Version 2, available from the file
|
||||
* COPYING in the main directory of this source tree, or the
|
||||
* OpenIB.org BSD license below:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or
|
||||
* without modification, are permitted provided that the following
|
||||
* conditions are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer.
|
||||
*
|
||||
* - Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <linux/kref.h>
|
||||
#include <linux/list.h>
|
||||
|
||||
struct sock;
|
||||
|
||||
#define TLS_TOE_DEVICE_NAME_MAX 32
|
||||
|
||||
/*
|
||||
* This structure defines the routines for Inline TLS driver.
|
||||
* The following routines are optional and filled with a
|
||||
* null pointer if not defined.
|
||||
*
|
||||
* @name: Its the name of registered Inline tls device
|
||||
* @dev_list: Inline tls device list
|
||||
* int (*feature)(struct tls_toe_device *device);
|
||||
* Called to return Inline TLS driver capability
|
||||
*
|
||||
* int (*hash)(struct tls_toe_device *device, struct sock *sk);
|
||||
* This function sets Inline driver for listen and program
|
||||
* device specific functioanlity as required
|
||||
*
|
||||
* void (*unhash)(struct tls_toe_device *device, struct sock *sk);
|
||||
* This function cleans listen state set by Inline TLS driver
|
||||
*
|
||||
* void (*release)(struct kref *kref);
|
||||
* Release the registered device and allocated resources
|
||||
* @kref: Number of reference to tls_toe_device
|
||||
*/
|
||||
struct tls_toe_device {
|
||||
char name[TLS_TOE_DEVICE_NAME_MAX];
|
||||
struct list_head dev_list;
|
||||
int (*feature)(struct tls_toe_device *device);
|
||||
int (*hash)(struct tls_toe_device *device, struct sock *sk);
|
||||
void (*unhash)(struct tls_toe_device *device, struct sock *sk);
|
||||
void (*release)(struct kref *kref);
|
||||
struct kref kref;
|
||||
};
|
||||
|
||||
int tls_toe_bypass(struct sock *sk);
|
||||
int tls_toe_hash(struct sock *sk);
|
||||
void tls_toe_unhash(struct sock *sk);
|
||||
|
||||
void tls_toe_register_device(struct tls_toe_device *device);
|
||||
void tls_toe_unregister_device(struct tls_toe_device *device);
|
||||
@@ -203,6 +203,6 @@ enum {
|
||||
#define TLS_CONF_BASE 1
|
||||
#define TLS_CONF_SW 2
|
||||
#define TLS_CONF_HW 3
|
||||
#define TLS_CONF_HW_RECORD 4
|
||||
#define TLS_CONF_HW_RECORD 4 /* unused */
|
||||
|
||||
#endif /* _UAPI_LINUX_TLS_H */
|
||||
|
||||
@@ -67,7 +67,6 @@ const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] = {
|
||||
[NETIF_F_HW_ESP_BIT] = "esp-hw-offload",
|
||||
[NETIF_F_HW_ESP_TX_CSUM_BIT] = "esp-tx-csum-hw-offload",
|
||||
[NETIF_F_RX_UDP_TUNNEL_PORT_BIT] = "rx-udp_tunnel-port-offload",
|
||||
[NETIF_F_HW_TLS_RECORD_BIT] = "tls-hw-record",
|
||||
[NETIF_F_HW_TLS_TX_BIT] = "tls-hw-tx-offload",
|
||||
[NETIF_F_HW_TLS_RX_BIT] = "tls-hw-rx-offload",
|
||||
[NETIF_F_GRO_FRAGLIST_BIT] = "rx-gro-list",
|
||||
|
||||
@@ -27,13 +27,3 @@ config TLS_DEVICE
|
||||
Enable kernel support for HW offload of the TLS protocol.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config TLS_TOE
|
||||
bool "Transport Layer Security TCP stack bypass"
|
||||
depends on TLS
|
||||
default n
|
||||
help
|
||||
Enable kernel support for legacy HW offload of the TLS protocol,
|
||||
which is incompatible with the Linux networking stack semantics.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
@@ -9,5 +9,4 @@ obj-$(CONFIG_TLS) += tls.o
|
||||
|
||||
tls-y := tls_main.o tls_sw.o tls_proc.o trace.o tls_strp.o
|
||||
|
||||
tls-$(CONFIG_TLS_TOE) += tls_toe.o
|
||||
tls-$(CONFIG_TLS_DEVICE) += tls_device.o tls_device_fallback.o
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user