summaryrefslogtreecommitdiff
path: root/net/tls/tls_main.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-08-29 21:33:01 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2023-08-29 21:33:01 +0300
commitbd6c11bc43c496cddfc6cf603b5d45365606dbd5 (patch)
tree36318fa68f784d397111991177d65bd6325189c4 /net/tls/tls_main.c
parent68cf01760bc0891074e813b9bb06d2696cac1c01 (diff)
parentc873512ef3a39cc1a605b7a5ff2ad0a33d619aa8 (diff)
downloadlinux-bd6c11bc43c496cddfc6cf603b5d45365606dbd5.tar.xz
Merge tag 'net-next-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next
Pull networking updates from Paolo Abeni: "Core: - Increase size limits for to-be-sent skb frag allocations. This allows tun, tap devices and packet sockets to better cope with large writes operations - Store netdevs in an xarray, to simplify iterating over netdevs - Refactor nexthop selection for multipath routes - Improve sched class lifetime handling - Add backup nexthop ID support for bridge - Implement drop reasons support in openvswitch - Several data races annotations and fixes - Constify the sk parameter of routing functions - Prepend kernel version to netconsole message Protocols: - Implement support for TCP probing the peer being under memory pressure - Remove hard coded limitation on IPv6 specific info placement inside the socket struct - Get rid of sysctl_tcp_adv_win_scale and use an auto-estimated per socket scaling factor - Scaling-up the IPv6 expired route GC via a separated list of expiring routes - In-kernel support for the TLS alert protocol - Better support for UDP reuseport with connected sockets - Add NEXT-C-SID support for SRv6 End.X behavior, reducing the SR header size - Get rid of additional ancillary per MPTCP connection struct socket - Implement support for BPF-based MPTCP packet schedulers - Format MPTCP subtests selftests results in TAP - Several new SMC 2.1 features including unique experimental options, max connections per lgr negotiation, max links per lgr negotiation BPF: - Multi-buffer support in AF_XDP - Add multi uprobe BPF links for attaching multiple uprobes and usdt probes, which is significantly faster and saves extra fds - Implement an fd-based tc BPF attach API (TCX) and BPF link support on top of it - Add SO_REUSEPORT support for TC bpf_sk_assign - Support new instructions from cpu v4 to simplify the generated code and feature completeness, for x86, arm64, riscv64 - Support defragmenting IPv(4|6) packets in BPF - Teach verifier actual bounds of bpf_get_smp_processor_id() and fix perf+libbpf issue related to custom section handling - Introduce bpf map element count and enable it for all program types - Add a BPF hook in sys_socket() to change the protocol ID from IPPROTO_TCP to IPPROTO_MPTCP to cover migration for legacy - Introduce bpf_me_mcache_free_rcu() and fix OOM under stress - Add uprobe support for the bpf_get_func_ip helper - Check skb ownership against full socket - Support for up to 12 arguments in BPF trampoline - Extend link_info for kprobe_multi and perf_event links Netfilter: - Speed-up process exit by aborting ruleset validation if a fatal signal is pending - Allow NLA_POLICY_MASK to be used with BE16/BE32 types Driver API: - Page pool optimizations, to improve data locality and cache usage - Introduce ndo_hwtstamp_get() and ndo_hwtstamp_set() to avoid the need for raw ioctl() handling in drivers - Simplify genetlink dump operations (doit/dumpit) providing them the common information already populated in struct genl_info - Extend and use the yaml devlink specs to [re]generate the split ops - Introduce devlink selective dumps, to allow SF filtering SF based on handle and other attributes - Add yaml netlink spec for netlink-raw families, allow route, link and address related queries via the ynl tool - Remove phylink legacy mode support - Support offload LED blinking to phy - Add devlink port function attributes for IPsec New hardware / drivers: - Ethernet: - Broadcom ASP 2.0 (72165) ethernet controller - MediaTek MT7988 SoC - Texas Instruments AM654 SoC - Texas Instruments IEP driver - Atheros qca8081 phy - Marvell 88Q2110 phy - NXP TJA1120 phy - WiFi: - MediaTek mt7981 support - Can: - Kvaser SmartFusion2 PCI Express devices - Allwinner T113 controllers - Texas Instruments tcan4552/4553 chips - Bluetooth: - Intel Gale Peak - Qualcomm WCN3988 and WCN7850 - NXP AW693 and IW624 - Mediatek MT2925 Drivers: - Ethernet NICs: - nVidia/Mellanox: - mlx5: - support UDP encapsulation in packet offload mode - IPsec packet offload support in eswitch mode - improve aRFS observability by adding new set of counters - extends MACsec offload support to cover RoCE traffic - dynamic completion EQs - mlx4: - convert to use auxiliary bus instead of custom interface logic - Intel - ice: - implement switchdev bridge offload, even for LAG interfaces - implement SRIOV support for LAG interfaces - igc: - add support for multiple in-flight TX timestamps - Broadcom: - bnxt: - use the unified RX page pool buffers for XDP and non-XDP - use the NAPI skb allocation cache - OcteonTX2: - support Round Robin scheduling HTB offload - TC flower offload support for SPI field - Freescale: - add XDP_TX feature support - AMD: - ionic: add support for PCI FLR event - sfc: - basic conntrack offload - introduce eth, ipv4 and ipv6 pedit offloads - ST Microelectronics: - stmmac: maximze PTP timestamping resolution - Virtual NICs: - Microsoft vNIC: - batch ringing RX queue doorbell on receiving packets - add page pool for RX buffers - Virtio vNIC: - add per queue interrupt coalescing support - Google vNIC: - add queue-page-list mode support - Ethernet high-speed switches: - nVidia/Mellanox (mlxsw): - add port range matching tc-flower offload - permit enslavement to netdevices with uppers - Ethernet embedded switches: - Marvell (mv88e6xxx): - convert to phylink_pcs - Renesas: - r8A779fx: add speed change support - rzn1: enables vlan support - Ethernet PHYs: - convert mv88e6xxx to phylink_pcs - WiFi: - Qualcomm Wi-Fi 7 (ath12k): - extremely High Throughput (EHT) PHY support - RealTek (rtl8xxxu): - enable AP mode for: RTL8192FU, RTL8710BU (RTL8188GU), RTL8192EU and RTL8723BU - RealTek (rtw89): - Introduce Time Averaged SAR (TAS) support - Connector: - support for event filtering" * tag 'net-next-6.6' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1806 commits) net: ethernet: mtk_wed: minor change in wed_{tx,rx}info_show net: ethernet: mtk_wed: add some more info in wed_txinfo_show handler net: stmmac: clarify difference between "interface" and "phy_interface" r8152: add vendor/device ID pair for D-Link DUB-E250 devlink: move devlink_notify_register/unregister() to dev.c devlink: move small_ops definition into netlink.c devlink: move tracepoint definitions into core.c devlink: push linecard related code into separate file devlink: push rate related code into separate file devlink: push trap related code into separate file devlink: use tracepoint_enabled() helper devlink: push region related code into separate file devlink: push param related code into separate file devlink: push resource related code into separate file devlink: push dpipe related code into separate file devlink: move and rename devlink_dpipe_send_and_alloc_skb() helper devlink: push shared buffer related code into separate file devlink: push port related code into separate file devlink: push object register/unregister notifications into separate helpers inet: fix IP_TRANSPARENT error handling ...
Diffstat (limited to 'net/tls/tls_main.c')
-rw-r--r--net/tls/tls_main.c274
1 files changed, 72 insertions, 202 deletions
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c
index 4a8ee2f6badb..02f583ff9239 100644
--- a/net/tls/tls_main.c
+++ b/net/tls/tls_main.c
@@ -58,23 +58,66 @@ enum {
TLS_NUM_PROTS,
};
-#define CIPHER_SIZE_DESC(cipher) [cipher] = { \
+#define CHECK_CIPHER_DESC(cipher,ci) \
+ static_assert(cipher ## _IV_SIZE <= MAX_IV_SIZE); \
+ static_assert(cipher ## _REC_SEQ_SIZE <= TLS_MAX_REC_SEQ_SIZE); \
+ static_assert(cipher ## _TAG_SIZE == TLS_TAG_SIZE); \
+ static_assert(sizeof_field(struct ci, iv) == cipher ## _IV_SIZE); \
+ static_assert(sizeof_field(struct ci, key) == cipher ## _KEY_SIZE); \
+ static_assert(sizeof_field(struct ci, salt) == cipher ## _SALT_SIZE); \
+ static_assert(sizeof_field(struct ci, rec_seq) == cipher ## _REC_SEQ_SIZE);
+
+#define __CIPHER_DESC(ci) \
+ .iv_offset = offsetof(struct ci, iv), \
+ .key_offset = offsetof(struct ci, key), \
+ .salt_offset = offsetof(struct ci, salt), \
+ .rec_seq_offset = offsetof(struct ci, rec_seq), \
+ .crypto_info = sizeof(struct ci)
+
+#define CIPHER_DESC(cipher,ci,algname,_offloadable) [cipher - TLS_CIPHER_MIN] = { \
+ .nonce = cipher ## _IV_SIZE, \
.iv = cipher ## _IV_SIZE, \
.key = cipher ## _KEY_SIZE, \
.salt = cipher ## _SALT_SIZE, \
.tag = cipher ## _TAG_SIZE, \
.rec_seq = cipher ## _REC_SEQ_SIZE, \
+ .cipher_name = algname, \
+ .offloadable = _offloadable, \
+ __CIPHER_DESC(ci), \
}
-const struct tls_cipher_size_desc tls_cipher_size_desc[] = {
- CIPHER_SIZE_DESC(TLS_CIPHER_AES_GCM_128),
- CIPHER_SIZE_DESC(TLS_CIPHER_AES_GCM_256),
- CIPHER_SIZE_DESC(TLS_CIPHER_AES_CCM_128),
- CIPHER_SIZE_DESC(TLS_CIPHER_CHACHA20_POLY1305),
- CIPHER_SIZE_DESC(TLS_CIPHER_SM4_GCM),
- CIPHER_SIZE_DESC(TLS_CIPHER_SM4_CCM),
+#define CIPHER_DESC_NONCE0(cipher,ci,algname,_offloadable) [cipher - TLS_CIPHER_MIN] = { \
+ .nonce = 0, \
+ .iv = cipher ## _IV_SIZE, \
+ .key = cipher ## _KEY_SIZE, \
+ .salt = cipher ## _SALT_SIZE, \
+ .tag = cipher ## _TAG_SIZE, \
+ .rec_seq = cipher ## _REC_SEQ_SIZE, \
+ .cipher_name = algname, \
+ .offloadable = _offloadable, \
+ __CIPHER_DESC(ci), \
+}
+
+const struct tls_cipher_desc tls_cipher_desc[TLS_CIPHER_MAX + 1 - TLS_CIPHER_MIN] = {
+ CIPHER_DESC(TLS_CIPHER_AES_GCM_128, tls12_crypto_info_aes_gcm_128, "gcm(aes)", true),
+ CIPHER_DESC(TLS_CIPHER_AES_GCM_256, tls12_crypto_info_aes_gcm_256, "gcm(aes)", true),
+ CIPHER_DESC(TLS_CIPHER_AES_CCM_128, tls12_crypto_info_aes_ccm_128, "ccm(aes)", false),
+ CIPHER_DESC_NONCE0(TLS_CIPHER_CHACHA20_POLY1305, tls12_crypto_info_chacha20_poly1305, "rfc7539(chacha20,poly1305)", false),
+ CIPHER_DESC(TLS_CIPHER_SM4_GCM, tls12_crypto_info_sm4_gcm, "gcm(sm4)", false),
+ CIPHER_DESC(TLS_CIPHER_SM4_CCM, tls12_crypto_info_sm4_ccm, "ccm(sm4)", false),
+ CIPHER_DESC(TLS_CIPHER_ARIA_GCM_128, tls12_crypto_info_aria_gcm_128, "gcm(aria)", false),
+ CIPHER_DESC(TLS_CIPHER_ARIA_GCM_256, tls12_crypto_info_aria_gcm_256, "gcm(aria)", false),
};
+CHECK_CIPHER_DESC(TLS_CIPHER_AES_GCM_128, tls12_crypto_info_aes_gcm_128);
+CHECK_CIPHER_DESC(TLS_CIPHER_AES_GCM_256, tls12_crypto_info_aes_gcm_256);
+CHECK_CIPHER_DESC(TLS_CIPHER_AES_CCM_128, tls12_crypto_info_aes_ccm_128);
+CHECK_CIPHER_DESC(TLS_CIPHER_CHACHA20_POLY1305, tls12_crypto_info_chacha20_poly1305);
+CHECK_CIPHER_DESC(TLS_CIPHER_SM4_GCM, tls12_crypto_info_sm4_gcm);
+CHECK_CIPHER_DESC(TLS_CIPHER_SM4_CCM, tls12_crypto_info_sm4_ccm);
+CHECK_CIPHER_DESC(TLS_CIPHER_ARIA_GCM_128, tls12_crypto_info_aria_gcm_128);
+CHECK_CIPHER_DESC(TLS_CIPHER_ARIA_GCM_256, tls12_crypto_info_aria_gcm_256);
+
static const struct proto *saved_tcpv6_prot;
static DEFINE_MUTEX(tcpv6_prot_mutex);
static const struct proto *saved_tcpv4_prot;
@@ -392,6 +435,7 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
int __user *optlen, int tx)
{
int rc = 0;
+ const struct tls_cipher_desc *cipher_desc;
struct tls_context *ctx = tls_get_ctx(sk);
struct tls_crypto_info *crypto_info;
struct cipher_context *cctx;
@@ -430,172 +474,19 @@ static int do_tls_getsockopt_conf(struct sock *sk, char __user *optval,
goto out;
}
- switch (crypto_info->cipher_type) {
- case TLS_CIPHER_AES_GCM_128: {
- struct tls12_crypto_info_aes_gcm_128 *
- crypto_info_aes_gcm_128 =
- container_of(crypto_info,
- struct tls12_crypto_info_aes_gcm_128,
- info);
-
- if (len != sizeof(*crypto_info_aes_gcm_128)) {
- rc = -EINVAL;
- goto out;
- }
- memcpy(crypto_info_aes_gcm_128->iv,
- cctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
- TLS_CIPHER_AES_GCM_128_IV_SIZE);
- memcpy(crypto_info_aes_gcm_128->rec_seq, cctx->rec_seq,
- TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE);
- if (copy_to_user(optval,
- crypto_info_aes_gcm_128,
- sizeof(*crypto_info_aes_gcm_128)))
- rc = -EFAULT;
- break;
- }
- case TLS_CIPHER_AES_GCM_256: {
- struct tls12_crypto_info_aes_gcm_256 *
- crypto_info_aes_gcm_256 =
- container_of(crypto_info,
- struct tls12_crypto_info_aes_gcm_256,
- info);
-
- if (len != sizeof(*crypto_info_aes_gcm_256)) {
- rc = -EINVAL;
- goto out;
- }
- memcpy(crypto_info_aes_gcm_256->iv,
- cctx->iv + TLS_CIPHER_AES_GCM_256_SALT_SIZE,
- TLS_CIPHER_AES_GCM_256_IV_SIZE);
- memcpy(crypto_info_aes_gcm_256->rec_seq, cctx->rec_seq,
- TLS_CIPHER_AES_GCM_256_REC_SEQ_SIZE);
- if (copy_to_user(optval,
- crypto_info_aes_gcm_256,
- sizeof(*crypto_info_aes_gcm_256)))
- rc = -EFAULT;
- break;
- }
- case TLS_CIPHER_AES_CCM_128: {
- struct tls12_crypto_info_aes_ccm_128 *aes_ccm_128 =
- container_of(crypto_info,
- struct tls12_crypto_info_aes_ccm_128, info);
-
- if (len != sizeof(*aes_ccm_128)) {
- rc = -EINVAL;
- goto out;
- }
- memcpy(aes_ccm_128->iv,
- cctx->iv + TLS_CIPHER_AES_CCM_128_SALT_SIZE,
- TLS_CIPHER_AES_CCM_128_IV_SIZE);
- memcpy(aes_ccm_128->rec_seq, cctx->rec_seq,
- TLS_CIPHER_AES_CCM_128_REC_SEQ_SIZE);
- if (copy_to_user(optval, aes_ccm_128, sizeof(*aes_ccm_128)))
- rc = -EFAULT;
- break;
- }
- case TLS_CIPHER_CHACHA20_POLY1305: {
- struct tls12_crypto_info_chacha20_poly1305 *chacha20_poly1305 =
- container_of(crypto_info,
- struct tls12_crypto_info_chacha20_poly1305,
- info);
-
- if (len != sizeof(*chacha20_poly1305)) {
- rc = -EINVAL;
- goto out;
- }
- memcpy(chacha20_poly1305->iv,
- cctx->iv + TLS_CIPHER_CHACHA20_POLY1305_SALT_SIZE,
- TLS_CIPHER_CHACHA20_POLY1305_IV_SIZE);
- memcpy(chacha20_poly1305->rec_seq, cctx->rec_seq,
- TLS_CIPHER_CHACHA20_POLY1305_REC_SEQ_SIZE);
- if (copy_to_user(optval, chacha20_poly1305,
- sizeof(*chacha20_poly1305)))
- rc = -EFAULT;
- break;
+ cipher_desc = get_cipher_desc(crypto_info->cipher_type);
+ if (!cipher_desc || len != cipher_desc->crypto_info) {
+ rc = -EINVAL;
+ goto out;
}
- case TLS_CIPHER_SM4_GCM: {
- struct tls12_crypto_info_sm4_gcm *sm4_gcm_info =
- container_of(crypto_info,
- struct tls12_crypto_info_sm4_gcm, info);
- if (len != sizeof(*sm4_gcm_info)) {
- rc = -EINVAL;
- goto out;
- }
- memcpy(sm4_gcm_info->iv,
- cctx->iv + TLS_CIPHER_SM4_GCM_SALT_SIZE,
- TLS_CIPHER_SM4_GCM_IV_SIZE);
- memcpy(sm4_gcm_info->rec_seq, cctx->rec_seq,
- TLS_CIPHER_SM4_GCM_REC_SEQ_SIZE);
- if (copy_to_user(optval, sm4_gcm_info, sizeof(*sm4_gcm_info)))
- rc = -EFAULT;
- break;
- }
- case TLS_CIPHER_SM4_CCM: {
- struct tls12_crypto_info_sm4_ccm *sm4_ccm_info =
- container_of(crypto_info,
- struct tls12_crypto_info_sm4_ccm, info);
+ memcpy(crypto_info_iv(crypto_info, cipher_desc),
+ cctx->iv + cipher_desc->salt, cipher_desc->iv);
+ memcpy(crypto_info_rec_seq(crypto_info, cipher_desc),
+ cctx->rec_seq, cipher_desc->rec_seq);
- if (len != sizeof(*sm4_ccm_info)) {
- rc = -EINVAL;
- goto out;
- }
- memcpy(sm4_ccm_info->iv,
- cctx->iv + TLS_CIPHER_SM4_CCM_SALT_SIZE,
- TLS_CIPHER_SM4_CCM_IV_SIZE);
- memcpy(sm4_ccm_info->rec_seq, cctx->rec_seq,
- TLS_CIPHER_SM4_CCM_REC_SEQ_SIZE);
- if (copy_to_user(optval, sm4_ccm_info, sizeof(*sm4_ccm_info)))
- rc = -EFAULT;
- break;
- }
- case TLS_CIPHER_ARIA_GCM_128: {
- struct tls12_crypto_info_aria_gcm_128 *
- crypto_info_aria_gcm_128 =
- container_of(crypto_info,
- struct tls12_crypto_info_aria_gcm_128,
- info);
-
- if (len != sizeof(*crypto_info_aria_gcm_128)) {
- rc = -EINVAL;
- goto out;
- }
- memcpy(crypto_info_aria_gcm_128->iv,
- cctx->iv + TLS_CIPHER_ARIA_GCM_128_SALT_SIZE,
- TLS_CIPHER_ARIA_GCM_128_IV_SIZE);
- memcpy(crypto_info_aria_gcm_128->rec_seq, cctx->rec_seq,
- TLS_CIPHER_ARIA_GCM_128_REC_SEQ_SIZE);
- if (copy_to_user(optval,
- crypto_info_aria_gcm_128,
- sizeof(*crypto_info_aria_gcm_128)))
- rc = -EFAULT;
- break;
- }
- case TLS_CIPHER_ARIA_GCM_256: {
- struct tls12_crypto_info_aria_gcm_256 *
- crypto_info_aria_gcm_256 =
- container_of(crypto_info,
- struct tls12_crypto_info_aria_gcm_256,
- info);
-
- if (len != sizeof(*crypto_info_aria_gcm_256)) {
- rc = -EINVAL;
- goto out;
- }
- memcpy(crypto_info_aria_gcm_256->iv,
- cctx->iv + TLS_CIPHER_ARIA_GCM_256_SALT_SIZE,
- TLS_CIPHER_ARIA_GCM_256_IV_SIZE);
- memcpy(crypto_info_aria_gcm_256->rec_seq, cctx->rec_seq,
- TLS_CIPHER_ARIA_GCM_256_REC_SEQ_SIZE);
- if (copy_to_user(optval,
- crypto_info_aria_gcm_256,
- sizeof(*crypto_info_aria_gcm_256)))
- rc = -EFAULT;
- break;
- }
- default:
- rc = -EINVAL;
- }
+ if (copy_to_user(optval, crypto_info, cipher_desc->crypto_info))
+ rc = -EFAULT;
out:
return rc;
@@ -696,7 +587,7 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
struct tls_crypto_info *crypto_info;
struct tls_crypto_info *alt_crypto_info;
struct tls_context *ctx = tls_get_ctx(sk);
- size_t optsize;
+ const struct tls_cipher_desc *cipher_desc;
int rc = 0;
int conf;
@@ -737,46 +628,23 @@ static int do_tls_setsockopt_conf(struct sock *sk, sockptr_t optval,
}
}
- switch (crypto_info->cipher_type) {
- case TLS_CIPHER_AES_GCM_128:
- optsize = sizeof(struct tls12_crypto_info_aes_gcm_128);
- break;
- case TLS_CIPHER_AES_GCM_256: {
- optsize = sizeof(struct tls12_crypto_info_aes_gcm_256);
- break;
+ cipher_desc = get_cipher_desc(crypto_info->cipher_type);
+ if (!cipher_desc) {
+ rc = -EINVAL;
+ goto err_crypto_info;
}
- case TLS_CIPHER_AES_CCM_128:
- optsize = sizeof(struct tls12_crypto_info_aes_ccm_128);
- break;
- case TLS_CIPHER_CHACHA20_POLY1305:
- optsize = sizeof(struct tls12_crypto_info_chacha20_poly1305);
- break;
- case TLS_CIPHER_SM4_GCM:
- optsize = sizeof(struct tls12_crypto_info_sm4_gcm);
- break;
- case TLS_CIPHER_SM4_CCM:
- optsize = sizeof(struct tls12_crypto_info_sm4_ccm);
- break;
+
+ switch (crypto_info->cipher_type) {
case TLS_CIPHER_ARIA_GCM_128:
- if (crypto_info->version != TLS_1_2_VERSION) {
- rc = -EINVAL;
- goto err_crypto_info;
- }
- optsize = sizeof(struct tls12_crypto_info_aria_gcm_128);
- break;
case TLS_CIPHER_ARIA_GCM_256:
if (crypto_info->version != TLS_1_2_VERSION) {
rc = -EINVAL;
goto err_crypto_info;
}
- optsize = sizeof(struct tls12_crypto_info_aria_gcm_256);
break;
- default:
- rc = -EINVAL;
- goto err_crypto_info;
}
- if (optlen != optsize) {
+ if (optlen != cipher_desc->crypto_info) {
rc = -EINVAL;
goto err_crypto_info;
}
@@ -959,10 +827,12 @@ static void build_proto_ops(struct proto_ops ops[TLS_NUM_CONFIG][TLS_NUM_CONFIG]
ops[TLS_BASE][TLS_SW ] = ops[TLS_BASE][TLS_BASE];
ops[TLS_BASE][TLS_SW ].splice_read = tls_sw_splice_read;
ops[TLS_BASE][TLS_SW ].poll = tls_sk_poll;
+ ops[TLS_BASE][TLS_SW ].read_sock = tls_sw_read_sock;
ops[TLS_SW ][TLS_SW ] = ops[TLS_SW ][TLS_BASE];
ops[TLS_SW ][TLS_SW ].splice_read = tls_sw_splice_read;
ops[TLS_SW ][TLS_SW ].poll = tls_sk_poll;
+ ops[TLS_SW ][TLS_SW ].read_sock = tls_sw_read_sock;
#ifdef CONFIG_TLS_DEVICE
ops[TLS_HW ][TLS_BASE] = ops[TLS_BASE][TLS_BASE];