18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright (c) 2016-2017, Mellanox Technologies. All rights reserved.
38c2ecf20Sopenharmony_ci * Copyright (c) 2016-2017, Dave Watson <davejwatson@fb.com>. All rights reserved.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two
68c2ecf20Sopenharmony_ci * licenses.  You may choose to be licensed under the terms of the GNU
78c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file
88c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the
98c2ecf20Sopenharmony_ci * OpenIB.org BSD license below:
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci *     Redistribution and use in source and binary forms, with or
128c2ecf20Sopenharmony_ci *     without modification, are permitted provided that the following
138c2ecf20Sopenharmony_ci *     conditions are met:
148c2ecf20Sopenharmony_ci *
158c2ecf20Sopenharmony_ci *      - Redistributions of source code must retain the above
168c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
178c2ecf20Sopenharmony_ci *        disclaimer.
188c2ecf20Sopenharmony_ci *
198c2ecf20Sopenharmony_ci *      - Redistributions in binary form must reproduce the above
208c2ecf20Sopenharmony_ci *        copyright notice, this list of conditions and the following
218c2ecf20Sopenharmony_ci *        disclaimer in the documentation and/or other materials
228c2ecf20Sopenharmony_ci *        provided with the distribution.
238c2ecf20Sopenharmony_ci *
248c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
258c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
268c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
278c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
288c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
298c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
308c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
318c2ecf20Sopenharmony_ci * SOFTWARE.
328c2ecf20Sopenharmony_ci */
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci#ifndef _TLS_OFFLOAD_H
358c2ecf20Sopenharmony_ci#define _TLS_OFFLOAD_H
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci#include <linux/types.h>
388c2ecf20Sopenharmony_ci#include <asm/byteorder.h>
398c2ecf20Sopenharmony_ci#include <linux/crypto.h>
408c2ecf20Sopenharmony_ci#include <linux/socket.h>
418c2ecf20Sopenharmony_ci#include <linux/tcp.h>
428c2ecf20Sopenharmony_ci#include <linux/skmsg.h>
438c2ecf20Sopenharmony_ci#include <linux/mutex.h>
448c2ecf20Sopenharmony_ci#include <linux/netdevice.h>
458c2ecf20Sopenharmony_ci#include <linux/rcupdate.h>
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#include <net/net_namespace.h>
488c2ecf20Sopenharmony_ci#include <net/tcp.h>
498c2ecf20Sopenharmony_ci#include <net/strparser.h>
508c2ecf20Sopenharmony_ci#include <crypto/aead.h>
518c2ecf20Sopenharmony_ci#include <uapi/linux/tls.h>
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/* Maximum data size carried in a TLS record */
558c2ecf20Sopenharmony_ci#define TLS_MAX_PAYLOAD_SIZE		((size_t)1 << 14)
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci#define TLS_HEADER_SIZE			5
588c2ecf20Sopenharmony_ci#define TLS_NONCE_OFFSET		TLS_HEADER_SIZE
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci#define TLS_CRYPTO_INFO_READY(info)	((info)->cipher_type)
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci#define TLS_RECORD_TYPE_DATA		0x17
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci#define TLS_AAD_SPACE_SIZE		13
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci#define MAX_IV_SIZE			16
678c2ecf20Sopenharmony_ci#define TLS_MAX_REC_SEQ_SIZE		8
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci/* For AES-CCM, the full 16-bytes of IV is made of '4' fields of given sizes.
708c2ecf20Sopenharmony_ci *
718c2ecf20Sopenharmony_ci * IV[16] = b0[1] || implicit nonce[4] || explicit nonce[8] || length[3]
728c2ecf20Sopenharmony_ci *
738c2ecf20Sopenharmony_ci * The field 'length' is encoded in field 'b0' as '(length width - 1)'.
748c2ecf20Sopenharmony_ci * Hence b0 contains (3 - 1) = 2.
758c2ecf20Sopenharmony_ci */
768c2ecf20Sopenharmony_ci#define TLS_AES_CCM_IV_B0_BYTE		2
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci#define __TLS_INC_STATS(net, field)				\
798c2ecf20Sopenharmony_ci	__SNMP_INC_STATS((net)->mib.tls_statistics, field)
808c2ecf20Sopenharmony_ci#define TLS_INC_STATS(net, field)				\
818c2ecf20Sopenharmony_ci	SNMP_INC_STATS((net)->mib.tls_statistics, field)
828c2ecf20Sopenharmony_ci#define __TLS_DEC_STATS(net, field)				\
838c2ecf20Sopenharmony_ci	__SNMP_DEC_STATS((net)->mib.tls_statistics, field)
848c2ecf20Sopenharmony_ci#define TLS_DEC_STATS(net, field)				\
858c2ecf20Sopenharmony_ci	SNMP_DEC_STATS((net)->mib.tls_statistics, field)
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_cienum {
888c2ecf20Sopenharmony_ci	TLS_BASE,
898c2ecf20Sopenharmony_ci	TLS_SW,
908c2ecf20Sopenharmony_ci	TLS_HW,
918c2ecf20Sopenharmony_ci	TLS_HW_RECORD,
928c2ecf20Sopenharmony_ci	TLS_NUM_CONFIG,
938c2ecf20Sopenharmony_ci};
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ci/* TLS records are maintained in 'struct tls_rec'. It stores the memory pages
968c2ecf20Sopenharmony_ci * allocated or mapped for each TLS record. After encryption, the records are
978c2ecf20Sopenharmony_ci * stores in a linked list.
988c2ecf20Sopenharmony_ci */
998c2ecf20Sopenharmony_cistruct tls_rec {
1008c2ecf20Sopenharmony_ci	struct list_head list;
1018c2ecf20Sopenharmony_ci	int tx_ready;
1028c2ecf20Sopenharmony_ci	int tx_flags;
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	struct sk_msg msg_plaintext;
1058c2ecf20Sopenharmony_ci	struct sk_msg msg_encrypted;
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	/* AAD | msg_plaintext.sg.data | sg_tag */
1088c2ecf20Sopenharmony_ci	struct scatterlist sg_aead_in[2];
1098c2ecf20Sopenharmony_ci	/* AAD | msg_encrypted.sg.data (data contains overhead for hdr & iv & tag) */
1108c2ecf20Sopenharmony_ci	struct scatterlist sg_aead_out[2];
1118c2ecf20Sopenharmony_ci
1128c2ecf20Sopenharmony_ci	char content_type;
1138c2ecf20Sopenharmony_ci	struct scatterlist sg_content_type;
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	char aad_space[TLS_AAD_SPACE_SIZE];
1168c2ecf20Sopenharmony_ci	u8 iv_data[MAX_IV_SIZE];
1178c2ecf20Sopenharmony_ci	struct aead_request aead_req;
1188c2ecf20Sopenharmony_ci	u8 aead_req_ctx[];
1198c2ecf20Sopenharmony_ci};
1208c2ecf20Sopenharmony_ci
1218c2ecf20Sopenharmony_cistruct tls_msg {
1228c2ecf20Sopenharmony_ci	struct strp_msg rxm;
1238c2ecf20Sopenharmony_ci	u8 control;
1248c2ecf20Sopenharmony_ci};
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_cistruct tx_work {
1278c2ecf20Sopenharmony_ci	struct delayed_work work;
1288c2ecf20Sopenharmony_ci	struct sock *sk;
1298c2ecf20Sopenharmony_ci};
1308c2ecf20Sopenharmony_ci
1318c2ecf20Sopenharmony_cistruct tls_sw_context_tx {
1328c2ecf20Sopenharmony_ci	struct crypto_aead *aead_send;
1338c2ecf20Sopenharmony_ci	struct crypto_wait async_wait;
1348c2ecf20Sopenharmony_ci	struct tx_work tx_work;
1358c2ecf20Sopenharmony_ci	struct tls_rec *open_rec;
1368c2ecf20Sopenharmony_ci	struct list_head tx_list;
1378c2ecf20Sopenharmony_ci	atomic_t encrypt_pending;
1388c2ecf20Sopenharmony_ci	/* protect crypto_wait with encrypt_pending */
1398c2ecf20Sopenharmony_ci	spinlock_t encrypt_compl_lock;
1408c2ecf20Sopenharmony_ci	int async_notify;
1418c2ecf20Sopenharmony_ci	u8 async_capable:1;
1428c2ecf20Sopenharmony_ci
1438c2ecf20Sopenharmony_ci#define BIT_TX_SCHEDULED	0
1448c2ecf20Sopenharmony_ci#define BIT_TX_CLOSING		1
1458c2ecf20Sopenharmony_ci	unsigned long tx_bitmask;
1468c2ecf20Sopenharmony_ci};
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistruct tls_sw_context_rx {
1498c2ecf20Sopenharmony_ci	struct crypto_aead *aead_recv;
1508c2ecf20Sopenharmony_ci	struct crypto_wait async_wait;
1518c2ecf20Sopenharmony_ci	struct strparser strp;
1528c2ecf20Sopenharmony_ci	struct sk_buff_head rx_list;	/* list of decrypted 'data' records */
1538c2ecf20Sopenharmony_ci	void (*saved_data_ready)(struct sock *sk);
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	struct sk_buff *recv_pkt;
1568c2ecf20Sopenharmony_ci	u8 control;
1578c2ecf20Sopenharmony_ci	u8 async_capable:1;
1588c2ecf20Sopenharmony_ci	u8 decrypted:1;
1598c2ecf20Sopenharmony_ci	atomic_t decrypt_pending;
1608c2ecf20Sopenharmony_ci	/* protect crypto_wait with decrypt_pending*/
1618c2ecf20Sopenharmony_ci	spinlock_t decrypt_compl_lock;
1628c2ecf20Sopenharmony_ci	bool async_notify;
1638c2ecf20Sopenharmony_ci};
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_cistruct tls_record_info {
1668c2ecf20Sopenharmony_ci	struct list_head list;
1678c2ecf20Sopenharmony_ci	u32 end_seq;
1688c2ecf20Sopenharmony_ci	int len;
1698c2ecf20Sopenharmony_ci	int num_frags;
1708c2ecf20Sopenharmony_ci	skb_frag_t frags[MAX_SKB_FRAGS];
1718c2ecf20Sopenharmony_ci};
1728c2ecf20Sopenharmony_ci
1738c2ecf20Sopenharmony_cistruct tls_offload_context_tx {
1748c2ecf20Sopenharmony_ci	struct crypto_aead *aead_send;
1758c2ecf20Sopenharmony_ci	spinlock_t lock;	/* protects records list */
1768c2ecf20Sopenharmony_ci	struct list_head records_list;
1778c2ecf20Sopenharmony_ci	struct tls_record_info *open_record;
1788c2ecf20Sopenharmony_ci	struct tls_record_info *retransmit_hint;
1798c2ecf20Sopenharmony_ci	u64 hint_record_sn;
1808c2ecf20Sopenharmony_ci	u64 unacked_record_sn;
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_ci	struct scatterlist sg_tx_data[MAX_SKB_FRAGS];
1838c2ecf20Sopenharmony_ci	void (*sk_destruct)(struct sock *sk);
1848c2ecf20Sopenharmony_ci	u8 driver_state[] __aligned(8);
1858c2ecf20Sopenharmony_ci	/* The TLS layer reserves room for driver specific state
1868c2ecf20Sopenharmony_ci	 * Currently the belief is that there is not enough
1878c2ecf20Sopenharmony_ci	 * driver specific state to justify another layer of indirection
1888c2ecf20Sopenharmony_ci	 */
1898c2ecf20Sopenharmony_ci#define TLS_DRIVER_STATE_SIZE_TX	16
1908c2ecf20Sopenharmony_ci};
1918c2ecf20Sopenharmony_ci
1928c2ecf20Sopenharmony_ci#define TLS_OFFLOAD_CONTEXT_SIZE_TX                                            \
1938c2ecf20Sopenharmony_ci	(sizeof(struct tls_offload_context_tx) + TLS_DRIVER_STATE_SIZE_TX)
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cienum tls_context_flags {
1968c2ecf20Sopenharmony_ci	/* tls_device_down was called after the netdev went down, device state
1978c2ecf20Sopenharmony_ci	 * was released, and kTLS works in software, even though rx_conf is
1988c2ecf20Sopenharmony_ci	 * still TLS_HW (needed for transition).
1998c2ecf20Sopenharmony_ci	 */
2008c2ecf20Sopenharmony_ci	TLS_RX_DEV_DEGRADED = 0,
2018c2ecf20Sopenharmony_ci	/* Unlike RX where resync is driven entirely by the core in TX only
2028c2ecf20Sopenharmony_ci	 * the driver knows when things went out of sync, so we need the flag
2038c2ecf20Sopenharmony_ci	 * to be atomic.
2048c2ecf20Sopenharmony_ci	 */
2058c2ecf20Sopenharmony_ci	TLS_TX_SYNC_SCHED = 1,
2068c2ecf20Sopenharmony_ci	/* tls_dev_del was called for the RX side, device state was released,
2078c2ecf20Sopenharmony_ci	 * but tls_ctx->netdev might still be kept, because TX-side driver
2088c2ecf20Sopenharmony_ci	 * resources might not be released yet. Used to prevent the second
2098c2ecf20Sopenharmony_ci	 * tls_dev_del call in tls_device_down if it happens simultaneously.
2108c2ecf20Sopenharmony_ci	 */
2118c2ecf20Sopenharmony_ci	TLS_RX_DEV_CLOSED = 2,
2128c2ecf20Sopenharmony_ci};
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_cistruct cipher_context {
2158c2ecf20Sopenharmony_ci	char *iv;
2168c2ecf20Sopenharmony_ci	char *rec_seq;
2178c2ecf20Sopenharmony_ci};
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_ciunion tls_crypto_context {
2208c2ecf20Sopenharmony_ci	struct tls_crypto_info info;
2218c2ecf20Sopenharmony_ci	union {
2228c2ecf20Sopenharmony_ci		struct tls12_crypto_info_aes_gcm_128 aes_gcm_128;
2238c2ecf20Sopenharmony_ci		struct tls12_crypto_info_aes_gcm_256 aes_gcm_256;
2248c2ecf20Sopenharmony_ci	};
2258c2ecf20Sopenharmony_ci};
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_cistruct tls_prot_info {
2288c2ecf20Sopenharmony_ci	u16 version;
2298c2ecf20Sopenharmony_ci	u16 cipher_type;
2308c2ecf20Sopenharmony_ci	u16 prepend_size;
2318c2ecf20Sopenharmony_ci	u16 tag_size;
2328c2ecf20Sopenharmony_ci	u16 overhead_size;
2338c2ecf20Sopenharmony_ci	u16 iv_size;
2348c2ecf20Sopenharmony_ci	u16 salt_size;
2358c2ecf20Sopenharmony_ci	u16 rec_seq_size;
2368c2ecf20Sopenharmony_ci	u16 aad_size;
2378c2ecf20Sopenharmony_ci	u16 tail_size;
2388c2ecf20Sopenharmony_ci};
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_cistruct tls_context {
2418c2ecf20Sopenharmony_ci	/* read-only cache line */
2428c2ecf20Sopenharmony_ci	struct tls_prot_info prot_info;
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ci	u8 tx_conf:3;
2458c2ecf20Sopenharmony_ci	u8 rx_conf:3;
2468c2ecf20Sopenharmony_ci
2478c2ecf20Sopenharmony_ci	int (*push_pending_record)(struct sock *sk, int flags);
2488c2ecf20Sopenharmony_ci	void (*sk_write_space)(struct sock *sk);
2498c2ecf20Sopenharmony_ci
2508c2ecf20Sopenharmony_ci	void *priv_ctx_tx;
2518c2ecf20Sopenharmony_ci	void *priv_ctx_rx;
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ci	struct net_device *netdev;
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	/* rw cache line */
2568c2ecf20Sopenharmony_ci	struct cipher_context tx;
2578c2ecf20Sopenharmony_ci	struct cipher_context rx;
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci	struct scatterlist *partially_sent_record;
2608c2ecf20Sopenharmony_ci	u16 partially_sent_offset;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	bool in_tcp_sendpages;
2638c2ecf20Sopenharmony_ci	bool pending_open_record_frags;
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci	struct mutex tx_lock; /* protects partially_sent_* fields and
2668c2ecf20Sopenharmony_ci			       * per-type TX fields
2678c2ecf20Sopenharmony_ci			       */
2688c2ecf20Sopenharmony_ci	unsigned long flags;
2698c2ecf20Sopenharmony_ci
2708c2ecf20Sopenharmony_ci	/* cache cold stuff */
2718c2ecf20Sopenharmony_ci	struct proto *sk_proto;
2728c2ecf20Sopenharmony_ci	struct sock *sk;
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_ci	void (*sk_destruct)(struct sock *sk);
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci	union tls_crypto_context crypto_send;
2778c2ecf20Sopenharmony_ci	union tls_crypto_context crypto_recv;
2788c2ecf20Sopenharmony_ci
2798c2ecf20Sopenharmony_ci	struct list_head list;
2808c2ecf20Sopenharmony_ci	refcount_t refcount;
2818c2ecf20Sopenharmony_ci	struct rcu_head rcu;
2828c2ecf20Sopenharmony_ci};
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_cienum tls_offload_ctx_dir {
2858c2ecf20Sopenharmony_ci	TLS_OFFLOAD_CTX_DIR_RX,
2868c2ecf20Sopenharmony_ci	TLS_OFFLOAD_CTX_DIR_TX,
2878c2ecf20Sopenharmony_ci};
2888c2ecf20Sopenharmony_ci
2898c2ecf20Sopenharmony_cistruct tlsdev_ops {
2908c2ecf20Sopenharmony_ci	int (*tls_dev_add)(struct net_device *netdev, struct sock *sk,
2918c2ecf20Sopenharmony_ci			   enum tls_offload_ctx_dir direction,
2928c2ecf20Sopenharmony_ci			   struct tls_crypto_info *crypto_info,
2938c2ecf20Sopenharmony_ci			   u32 start_offload_tcp_sn);
2948c2ecf20Sopenharmony_ci	void (*tls_dev_del)(struct net_device *netdev,
2958c2ecf20Sopenharmony_ci			    struct tls_context *ctx,
2968c2ecf20Sopenharmony_ci			    enum tls_offload_ctx_dir direction);
2978c2ecf20Sopenharmony_ci	int (*tls_dev_resync)(struct net_device *netdev,
2988c2ecf20Sopenharmony_ci			      struct sock *sk, u32 seq, u8 *rcd_sn,
2998c2ecf20Sopenharmony_ci			      enum tls_offload_ctx_dir direction);
3008c2ecf20Sopenharmony_ci};
3018c2ecf20Sopenharmony_ci
3028c2ecf20Sopenharmony_cienum tls_offload_sync_type {
3038c2ecf20Sopenharmony_ci	TLS_OFFLOAD_SYNC_TYPE_DRIVER_REQ = 0,
3048c2ecf20Sopenharmony_ci	TLS_OFFLOAD_SYNC_TYPE_CORE_NEXT_HINT = 1,
3058c2ecf20Sopenharmony_ci	TLS_OFFLOAD_SYNC_TYPE_DRIVER_REQ_ASYNC = 2,
3068c2ecf20Sopenharmony_ci};
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci#define TLS_DEVICE_RESYNC_NH_START_IVAL		2
3098c2ecf20Sopenharmony_ci#define TLS_DEVICE_RESYNC_NH_MAX_IVAL		128
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci#define TLS_DEVICE_RESYNC_ASYNC_LOGMAX		13
3128c2ecf20Sopenharmony_cistruct tls_offload_resync_async {
3138c2ecf20Sopenharmony_ci	atomic64_t req;
3148c2ecf20Sopenharmony_ci	u16 loglen;
3158c2ecf20Sopenharmony_ci	u16 rcd_delta;
3168c2ecf20Sopenharmony_ci	u32 log[TLS_DEVICE_RESYNC_ASYNC_LOGMAX];
3178c2ecf20Sopenharmony_ci};
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_cistruct tls_offload_context_rx {
3208c2ecf20Sopenharmony_ci	/* sw must be the first member of tls_offload_context_rx */
3218c2ecf20Sopenharmony_ci	struct tls_sw_context_rx sw;
3228c2ecf20Sopenharmony_ci	enum tls_offload_sync_type resync_type;
3238c2ecf20Sopenharmony_ci	/* this member is set regardless of resync_type, to avoid branches */
3248c2ecf20Sopenharmony_ci	u8 resync_nh_reset:1;
3258c2ecf20Sopenharmony_ci	/* CORE_NEXT_HINT-only member, but use the hole here */
3268c2ecf20Sopenharmony_ci	u8 resync_nh_do_now:1;
3278c2ecf20Sopenharmony_ci	union {
3288c2ecf20Sopenharmony_ci		/* TLS_OFFLOAD_SYNC_TYPE_DRIVER_REQ */
3298c2ecf20Sopenharmony_ci		struct {
3308c2ecf20Sopenharmony_ci			atomic64_t resync_req;
3318c2ecf20Sopenharmony_ci		};
3328c2ecf20Sopenharmony_ci		/* TLS_OFFLOAD_SYNC_TYPE_CORE_NEXT_HINT */
3338c2ecf20Sopenharmony_ci		struct {
3348c2ecf20Sopenharmony_ci			u32 decrypted_failed;
3358c2ecf20Sopenharmony_ci			u32 decrypted_tgt;
3368c2ecf20Sopenharmony_ci		} resync_nh;
3378c2ecf20Sopenharmony_ci		/* TLS_OFFLOAD_SYNC_TYPE_DRIVER_REQ_ASYNC */
3388c2ecf20Sopenharmony_ci		struct {
3398c2ecf20Sopenharmony_ci			struct tls_offload_resync_async *resync_async;
3408c2ecf20Sopenharmony_ci		};
3418c2ecf20Sopenharmony_ci	};
3428c2ecf20Sopenharmony_ci	u8 driver_state[] __aligned(8);
3438c2ecf20Sopenharmony_ci	/* The TLS layer reserves room for driver specific state
3448c2ecf20Sopenharmony_ci	 * Currently the belief is that there is not enough
3458c2ecf20Sopenharmony_ci	 * driver specific state to justify another layer of indirection
3468c2ecf20Sopenharmony_ci	 */
3478c2ecf20Sopenharmony_ci#define TLS_DRIVER_STATE_SIZE_RX	8
3488c2ecf20Sopenharmony_ci};
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci#define TLS_OFFLOAD_CONTEXT_SIZE_RX					\
3518c2ecf20Sopenharmony_ci	(sizeof(struct tls_offload_context_rx) + TLS_DRIVER_STATE_SIZE_RX)
3528c2ecf20Sopenharmony_ci
3538c2ecf20Sopenharmony_cistruct tls_context *tls_ctx_create(struct sock *sk);
3548c2ecf20Sopenharmony_civoid tls_ctx_free(struct sock *sk, struct tls_context *ctx);
3558c2ecf20Sopenharmony_civoid update_sk_prot(struct sock *sk, struct tls_context *ctx);
3568c2ecf20Sopenharmony_ci
3578c2ecf20Sopenharmony_ciint wait_on_pending_writer(struct sock *sk, long *timeo);
3588c2ecf20Sopenharmony_ciint tls_sk_query(struct sock *sk, int optname, char __user *optval,
3598c2ecf20Sopenharmony_ci		int __user *optlen);
3608c2ecf20Sopenharmony_ciint tls_sk_attach(struct sock *sk, int optname, char __user *optval,
3618c2ecf20Sopenharmony_ci		  unsigned int optlen);
3628c2ecf20Sopenharmony_civoid tls_err_abort(struct sock *sk, int err);
3638c2ecf20Sopenharmony_ci
3648c2ecf20Sopenharmony_ciint tls_set_sw_offload(struct sock *sk, struct tls_context *ctx, int tx);
3658c2ecf20Sopenharmony_civoid tls_sw_strparser_arm(struct sock *sk, struct tls_context *ctx);
3668c2ecf20Sopenharmony_civoid tls_sw_strparser_done(struct tls_context *tls_ctx);
3678c2ecf20Sopenharmony_ciint tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
3688c2ecf20Sopenharmony_ciint tls_sw_sendpage_locked(struct sock *sk, struct page *page,
3698c2ecf20Sopenharmony_ci			   int offset, size_t size, int flags);
3708c2ecf20Sopenharmony_ciint tls_sw_sendpage(struct sock *sk, struct page *page,
3718c2ecf20Sopenharmony_ci		    int offset, size_t size, int flags);
3728c2ecf20Sopenharmony_civoid tls_sw_cancel_work_tx(struct tls_context *tls_ctx);
3738c2ecf20Sopenharmony_civoid tls_sw_release_resources_tx(struct sock *sk);
3748c2ecf20Sopenharmony_civoid tls_sw_free_ctx_tx(struct tls_context *tls_ctx);
3758c2ecf20Sopenharmony_civoid tls_sw_free_resources_rx(struct sock *sk);
3768c2ecf20Sopenharmony_civoid tls_sw_release_resources_rx(struct sock *sk);
3778c2ecf20Sopenharmony_civoid tls_sw_free_ctx_rx(struct tls_context *tls_ctx);
3788c2ecf20Sopenharmony_ciint tls_sw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
3798c2ecf20Sopenharmony_ci		   int nonblock, int flags, int *addr_len);
3808c2ecf20Sopenharmony_cibool tls_sw_stream_read(const struct sock *sk);
3818c2ecf20Sopenharmony_cissize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos,
3828c2ecf20Sopenharmony_ci			   struct pipe_inode_info *pipe,
3838c2ecf20Sopenharmony_ci			   size_t len, unsigned int flags);
3848c2ecf20Sopenharmony_ci
3858c2ecf20Sopenharmony_ciint tls_device_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
3868c2ecf20Sopenharmony_ciint tls_device_sendpage(struct sock *sk, struct page *page,
3878c2ecf20Sopenharmony_ci			int offset, size_t size, int flags);
3888c2ecf20Sopenharmony_ciint tls_tx_records(struct sock *sk, int flags);
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_cistruct tls_record_info *tls_get_record(struct tls_offload_context_tx *context,
3918c2ecf20Sopenharmony_ci				       u32 seq, u64 *p_record_sn);
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_cistatic inline bool tls_record_is_start_marker(struct tls_record_info *rec)
3948c2ecf20Sopenharmony_ci{
3958c2ecf20Sopenharmony_ci	return rec->len == 0;
3968c2ecf20Sopenharmony_ci}
3978c2ecf20Sopenharmony_ci
3988c2ecf20Sopenharmony_cistatic inline u32 tls_record_start_seq(struct tls_record_info *rec)
3998c2ecf20Sopenharmony_ci{
4008c2ecf20Sopenharmony_ci	return rec->end_seq - rec->len;
4018c2ecf20Sopenharmony_ci}
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ciint tls_push_sg(struct sock *sk, struct tls_context *ctx,
4048c2ecf20Sopenharmony_ci		struct scatterlist *sg, u16 first_offset,
4058c2ecf20Sopenharmony_ci		int flags);
4068c2ecf20Sopenharmony_ciint tls_push_partial_record(struct sock *sk, struct tls_context *ctx,
4078c2ecf20Sopenharmony_ci			    int flags);
4088c2ecf20Sopenharmony_civoid tls_free_partial_record(struct sock *sk, struct tls_context *ctx);
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_cistatic inline struct tls_msg *tls_msg(struct sk_buff *skb)
4118c2ecf20Sopenharmony_ci{
4128c2ecf20Sopenharmony_ci	return (struct tls_msg *)strp_msg(skb);
4138c2ecf20Sopenharmony_ci}
4148c2ecf20Sopenharmony_ci
4158c2ecf20Sopenharmony_cistatic inline bool tls_is_partially_sent_record(struct tls_context *ctx)
4168c2ecf20Sopenharmony_ci{
4178c2ecf20Sopenharmony_ci	return !!ctx->partially_sent_record;
4188c2ecf20Sopenharmony_ci}
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_cistatic inline bool tls_is_pending_open_record(struct tls_context *tls_ctx)
4218c2ecf20Sopenharmony_ci{
4228c2ecf20Sopenharmony_ci	return tls_ctx->pending_open_record_frags;
4238c2ecf20Sopenharmony_ci}
4248c2ecf20Sopenharmony_ci
4258c2ecf20Sopenharmony_cistatic inline bool is_tx_ready(struct tls_sw_context_tx *ctx)
4268c2ecf20Sopenharmony_ci{
4278c2ecf20Sopenharmony_ci	struct tls_rec *rec;
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_ci	rec = list_first_entry(&ctx->tx_list, struct tls_rec, list);
4308c2ecf20Sopenharmony_ci	if (!rec)
4318c2ecf20Sopenharmony_ci		return false;
4328c2ecf20Sopenharmony_ci
4338c2ecf20Sopenharmony_ci	return READ_ONCE(rec->tx_ready);
4348c2ecf20Sopenharmony_ci}
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_cistatic inline u16 tls_user_config(struct tls_context *ctx, bool tx)
4378c2ecf20Sopenharmony_ci{
4388c2ecf20Sopenharmony_ci	u16 config = tx ? ctx->tx_conf : ctx->rx_conf;
4398c2ecf20Sopenharmony_ci
4408c2ecf20Sopenharmony_ci	switch (config) {
4418c2ecf20Sopenharmony_ci	case TLS_BASE:
4428c2ecf20Sopenharmony_ci		return TLS_CONF_BASE;
4438c2ecf20Sopenharmony_ci	case TLS_SW:
4448c2ecf20Sopenharmony_ci		return TLS_CONF_SW;
4458c2ecf20Sopenharmony_ci	case TLS_HW:
4468c2ecf20Sopenharmony_ci		return TLS_CONF_HW;
4478c2ecf20Sopenharmony_ci	case TLS_HW_RECORD:
4488c2ecf20Sopenharmony_ci		return TLS_CONF_HW_RECORD;
4498c2ecf20Sopenharmony_ci	}
4508c2ecf20Sopenharmony_ci	return 0;
4518c2ecf20Sopenharmony_ci}
4528c2ecf20Sopenharmony_ci
4538c2ecf20Sopenharmony_cistruct sk_buff *
4548c2ecf20Sopenharmony_citls_validate_xmit_skb(struct sock *sk, struct net_device *dev,
4558c2ecf20Sopenharmony_ci		      struct sk_buff *skb);
4568c2ecf20Sopenharmony_cistruct sk_buff *
4578c2ecf20Sopenharmony_citls_validate_xmit_skb_sw(struct sock *sk, struct net_device *dev,
4588c2ecf20Sopenharmony_ci			 struct sk_buff *skb);
4598c2ecf20Sopenharmony_ci
4608c2ecf20Sopenharmony_cistatic inline bool tls_is_sk_tx_device_offloaded(struct sock *sk)
4618c2ecf20Sopenharmony_ci{
4628c2ecf20Sopenharmony_ci#ifdef CONFIG_SOCK_VALIDATE_XMIT
4638c2ecf20Sopenharmony_ci	return sk_fullsock(sk) &&
4648c2ecf20Sopenharmony_ci	       (smp_load_acquire(&sk->sk_validate_xmit_skb) ==
4658c2ecf20Sopenharmony_ci	       &tls_validate_xmit_skb);
4668c2ecf20Sopenharmony_ci#else
4678c2ecf20Sopenharmony_ci	return false;
4688c2ecf20Sopenharmony_ci#endif
4698c2ecf20Sopenharmony_ci}
4708c2ecf20Sopenharmony_ci
4718c2ecf20Sopenharmony_cistatic inline bool tls_bigint_increment(unsigned char *seq, int len)
4728c2ecf20Sopenharmony_ci{
4738c2ecf20Sopenharmony_ci	int i;
4748c2ecf20Sopenharmony_ci
4758c2ecf20Sopenharmony_ci	for (i = len - 1; i >= 0; i--) {
4768c2ecf20Sopenharmony_ci		++seq[i];
4778c2ecf20Sopenharmony_ci		if (seq[i] != 0)
4788c2ecf20Sopenharmony_ci			break;
4798c2ecf20Sopenharmony_ci	}
4808c2ecf20Sopenharmony_ci
4818c2ecf20Sopenharmony_ci	return (i == -1);
4828c2ecf20Sopenharmony_ci}
4838c2ecf20Sopenharmony_ci
4848c2ecf20Sopenharmony_cistatic inline void tls_bigint_subtract(unsigned char *seq, int  n)
4858c2ecf20Sopenharmony_ci{
4868c2ecf20Sopenharmony_ci	u64 rcd_sn;
4878c2ecf20Sopenharmony_ci	__be64 *p;
4888c2ecf20Sopenharmony_ci
4898c2ecf20Sopenharmony_ci	BUILD_BUG_ON(TLS_MAX_REC_SEQ_SIZE != 8);
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_ci	p = (__be64 *)seq;
4928c2ecf20Sopenharmony_ci	rcd_sn = be64_to_cpu(*p);
4938c2ecf20Sopenharmony_ci	*p = cpu_to_be64(rcd_sn - n);
4948c2ecf20Sopenharmony_ci}
4958c2ecf20Sopenharmony_ci
4968c2ecf20Sopenharmony_cistatic inline struct tls_context *tls_get_ctx(const struct sock *sk)
4978c2ecf20Sopenharmony_ci{
4988c2ecf20Sopenharmony_ci	struct inet_connection_sock *icsk = inet_csk(sk);
4998c2ecf20Sopenharmony_ci
5008c2ecf20Sopenharmony_ci	/* Use RCU on icsk_ulp_data only for sock diag code,
5018c2ecf20Sopenharmony_ci	 * TLS data path doesn't need rcu_dereference().
5028c2ecf20Sopenharmony_ci	 */
5038c2ecf20Sopenharmony_ci	return (__force void *)icsk->icsk_ulp_data;
5048c2ecf20Sopenharmony_ci}
5058c2ecf20Sopenharmony_ci
5068c2ecf20Sopenharmony_cistatic inline void tls_advance_record_sn(struct sock *sk,
5078c2ecf20Sopenharmony_ci					 struct tls_prot_info *prot,
5088c2ecf20Sopenharmony_ci					 struct cipher_context *ctx)
5098c2ecf20Sopenharmony_ci{
5108c2ecf20Sopenharmony_ci	if (tls_bigint_increment(ctx->rec_seq, prot->rec_seq_size))
5118c2ecf20Sopenharmony_ci		tls_err_abort(sk, -EBADMSG);
5128c2ecf20Sopenharmony_ci
5138c2ecf20Sopenharmony_ci	if (prot->version != TLS_1_3_VERSION)
5148c2ecf20Sopenharmony_ci		tls_bigint_increment(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE,
5158c2ecf20Sopenharmony_ci				     prot->iv_size);
5168c2ecf20Sopenharmony_ci}
5178c2ecf20Sopenharmony_ci
5188c2ecf20Sopenharmony_cistatic inline void tls_fill_prepend(struct tls_context *ctx,
5198c2ecf20Sopenharmony_ci			     char *buf,
5208c2ecf20Sopenharmony_ci			     size_t plaintext_len,
5218c2ecf20Sopenharmony_ci			     unsigned char record_type,
5228c2ecf20Sopenharmony_ci			     int version)
5238c2ecf20Sopenharmony_ci{
5248c2ecf20Sopenharmony_ci	struct tls_prot_info *prot = &ctx->prot_info;
5258c2ecf20Sopenharmony_ci	size_t pkt_len, iv_size = prot->iv_size;
5268c2ecf20Sopenharmony_ci
5278c2ecf20Sopenharmony_ci	pkt_len = plaintext_len + prot->tag_size;
5288c2ecf20Sopenharmony_ci	if (version != TLS_1_3_VERSION) {
5298c2ecf20Sopenharmony_ci		pkt_len += iv_size;
5308c2ecf20Sopenharmony_ci
5318c2ecf20Sopenharmony_ci		memcpy(buf + TLS_NONCE_OFFSET,
5328c2ecf20Sopenharmony_ci		       ctx->tx.iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv_size);
5338c2ecf20Sopenharmony_ci	}
5348c2ecf20Sopenharmony_ci
5358c2ecf20Sopenharmony_ci	/* we cover nonce explicit here as well, so buf should be of
5368c2ecf20Sopenharmony_ci	 * size KTLS_DTLS_HEADER_SIZE + KTLS_DTLS_NONCE_EXPLICIT_SIZE
5378c2ecf20Sopenharmony_ci	 */
5388c2ecf20Sopenharmony_ci	buf[0] = version == TLS_1_3_VERSION ?
5398c2ecf20Sopenharmony_ci		   TLS_RECORD_TYPE_DATA : record_type;
5408c2ecf20Sopenharmony_ci	/* Note that VERSION must be TLS_1_2 for both TLS1.2 and TLS1.3 */
5418c2ecf20Sopenharmony_ci	buf[1] = TLS_1_2_VERSION_MINOR;
5428c2ecf20Sopenharmony_ci	buf[2] = TLS_1_2_VERSION_MAJOR;
5438c2ecf20Sopenharmony_ci	/* we can use IV for nonce explicit according to spec */
5448c2ecf20Sopenharmony_ci	buf[3] = pkt_len >> 8;
5458c2ecf20Sopenharmony_ci	buf[4] = pkt_len & 0xFF;
5468c2ecf20Sopenharmony_ci}
5478c2ecf20Sopenharmony_ci
5488c2ecf20Sopenharmony_cistatic inline void tls_make_aad(char *buf,
5498c2ecf20Sopenharmony_ci				size_t size,
5508c2ecf20Sopenharmony_ci				char *record_sequence,
5518c2ecf20Sopenharmony_ci				int record_sequence_size,
5528c2ecf20Sopenharmony_ci				unsigned char record_type,
5538c2ecf20Sopenharmony_ci				int version)
5548c2ecf20Sopenharmony_ci{
5558c2ecf20Sopenharmony_ci	if (version != TLS_1_3_VERSION) {
5568c2ecf20Sopenharmony_ci		memcpy(buf, record_sequence, record_sequence_size);
5578c2ecf20Sopenharmony_ci		buf += 8;
5588c2ecf20Sopenharmony_ci	} else {
5598c2ecf20Sopenharmony_ci		size += TLS_CIPHER_AES_GCM_128_TAG_SIZE;
5608c2ecf20Sopenharmony_ci	}
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_ci	buf[0] = version == TLS_1_3_VERSION ?
5638c2ecf20Sopenharmony_ci		  TLS_RECORD_TYPE_DATA : record_type;
5648c2ecf20Sopenharmony_ci	buf[1] = TLS_1_2_VERSION_MAJOR;
5658c2ecf20Sopenharmony_ci	buf[2] = TLS_1_2_VERSION_MINOR;
5668c2ecf20Sopenharmony_ci	buf[3] = size >> 8;
5678c2ecf20Sopenharmony_ci	buf[4] = size & 0xFF;
5688c2ecf20Sopenharmony_ci}
5698c2ecf20Sopenharmony_ci
5708c2ecf20Sopenharmony_cistatic inline void xor_iv_with_seq(int version, char *iv, char *seq)
5718c2ecf20Sopenharmony_ci{
5728c2ecf20Sopenharmony_ci	int i;
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_ci	if (version == TLS_1_3_VERSION) {
5758c2ecf20Sopenharmony_ci		for (i = 0; i < 8; i++)
5768c2ecf20Sopenharmony_ci			iv[i + 4] ^= seq[i];
5778c2ecf20Sopenharmony_ci	}
5788c2ecf20Sopenharmony_ci}
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_ci
5818c2ecf20Sopenharmony_cistatic inline struct tls_sw_context_rx *tls_sw_ctx_rx(
5828c2ecf20Sopenharmony_ci		const struct tls_context *tls_ctx)
5838c2ecf20Sopenharmony_ci{
5848c2ecf20Sopenharmony_ci	return (struct tls_sw_context_rx *)tls_ctx->priv_ctx_rx;
5858c2ecf20Sopenharmony_ci}
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_cistatic inline struct tls_sw_context_tx *tls_sw_ctx_tx(
5888c2ecf20Sopenharmony_ci		const struct tls_context *tls_ctx)
5898c2ecf20Sopenharmony_ci{
5908c2ecf20Sopenharmony_ci	return (struct tls_sw_context_tx *)tls_ctx->priv_ctx_tx;
5918c2ecf20Sopenharmony_ci}
5928c2ecf20Sopenharmony_ci
5938c2ecf20Sopenharmony_cistatic inline struct tls_offload_context_tx *
5948c2ecf20Sopenharmony_citls_offload_ctx_tx(const struct tls_context *tls_ctx)
5958c2ecf20Sopenharmony_ci{
5968c2ecf20Sopenharmony_ci	return (struct tls_offload_context_tx *)tls_ctx->priv_ctx_tx;
5978c2ecf20Sopenharmony_ci}
5988c2ecf20Sopenharmony_ci
5998c2ecf20Sopenharmony_cistatic inline bool tls_sw_has_ctx_tx(const struct sock *sk)
6008c2ecf20Sopenharmony_ci{
6018c2ecf20Sopenharmony_ci	struct tls_context *ctx = tls_get_ctx(sk);
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci	if (!ctx)
6048c2ecf20Sopenharmony_ci		return false;
6058c2ecf20Sopenharmony_ci	return !!tls_sw_ctx_tx(ctx);
6068c2ecf20Sopenharmony_ci}
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_cistatic inline bool tls_sw_has_ctx_rx(const struct sock *sk)
6098c2ecf20Sopenharmony_ci{
6108c2ecf20Sopenharmony_ci	struct tls_context *ctx = tls_get_ctx(sk);
6118c2ecf20Sopenharmony_ci
6128c2ecf20Sopenharmony_ci	if (!ctx)
6138c2ecf20Sopenharmony_ci		return false;
6148c2ecf20Sopenharmony_ci	return !!tls_sw_ctx_rx(ctx);
6158c2ecf20Sopenharmony_ci}
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_civoid tls_sw_write_space(struct sock *sk, struct tls_context *ctx);
6188c2ecf20Sopenharmony_civoid tls_device_write_space(struct sock *sk, struct tls_context *ctx);
6198c2ecf20Sopenharmony_ci
6208c2ecf20Sopenharmony_cistatic inline struct tls_offload_context_rx *
6218c2ecf20Sopenharmony_citls_offload_ctx_rx(const struct tls_context *tls_ctx)
6228c2ecf20Sopenharmony_ci{
6238c2ecf20Sopenharmony_ci	return (struct tls_offload_context_rx *)tls_ctx->priv_ctx_rx;
6248c2ecf20Sopenharmony_ci}
6258c2ecf20Sopenharmony_ci
6268c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_TLS_DEVICE)
6278c2ecf20Sopenharmony_cistatic inline void *__tls_driver_ctx(struct tls_context *tls_ctx,
6288c2ecf20Sopenharmony_ci				     enum tls_offload_ctx_dir direction)
6298c2ecf20Sopenharmony_ci{
6308c2ecf20Sopenharmony_ci	if (direction == TLS_OFFLOAD_CTX_DIR_TX)
6318c2ecf20Sopenharmony_ci		return tls_offload_ctx_tx(tls_ctx)->driver_state;
6328c2ecf20Sopenharmony_ci	else
6338c2ecf20Sopenharmony_ci		return tls_offload_ctx_rx(tls_ctx)->driver_state;
6348c2ecf20Sopenharmony_ci}
6358c2ecf20Sopenharmony_ci
6368c2ecf20Sopenharmony_cistatic inline void *
6378c2ecf20Sopenharmony_citls_driver_ctx(const struct sock *sk, enum tls_offload_ctx_dir direction)
6388c2ecf20Sopenharmony_ci{
6398c2ecf20Sopenharmony_ci	return __tls_driver_ctx(tls_get_ctx(sk), direction);
6408c2ecf20Sopenharmony_ci}
6418c2ecf20Sopenharmony_ci#endif
6428c2ecf20Sopenharmony_ci
6438c2ecf20Sopenharmony_ci#define RESYNC_REQ BIT(0)
6448c2ecf20Sopenharmony_ci#define RESYNC_REQ_ASYNC BIT(1)
6458c2ecf20Sopenharmony_ci/* The TLS context is valid until sk_destruct is called */
6468c2ecf20Sopenharmony_cistatic inline void tls_offload_rx_resync_request(struct sock *sk, __be32 seq)
6478c2ecf20Sopenharmony_ci{
6488c2ecf20Sopenharmony_ci	struct tls_context *tls_ctx = tls_get_ctx(sk);
6498c2ecf20Sopenharmony_ci	struct tls_offload_context_rx *rx_ctx = tls_offload_ctx_rx(tls_ctx);
6508c2ecf20Sopenharmony_ci
6518c2ecf20Sopenharmony_ci	atomic64_set(&rx_ctx->resync_req, ((u64)ntohl(seq) << 32) | RESYNC_REQ);
6528c2ecf20Sopenharmony_ci}
6538c2ecf20Sopenharmony_ci
6548c2ecf20Sopenharmony_ci/* Log all TLS record header TCP sequences in [seq, seq+len] */
6558c2ecf20Sopenharmony_cistatic inline void
6568c2ecf20Sopenharmony_citls_offload_rx_resync_async_request_start(struct sock *sk, __be32 seq, u16 len)
6578c2ecf20Sopenharmony_ci{
6588c2ecf20Sopenharmony_ci	struct tls_context *tls_ctx = tls_get_ctx(sk);
6598c2ecf20Sopenharmony_ci	struct tls_offload_context_rx *rx_ctx = tls_offload_ctx_rx(tls_ctx);
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_ci	atomic64_set(&rx_ctx->resync_async->req, ((u64)ntohl(seq) << 32) |
6628c2ecf20Sopenharmony_ci		     ((u64)len << 16) | RESYNC_REQ | RESYNC_REQ_ASYNC);
6638c2ecf20Sopenharmony_ci	rx_ctx->resync_async->loglen = 0;
6648c2ecf20Sopenharmony_ci	rx_ctx->resync_async->rcd_delta = 0;
6658c2ecf20Sopenharmony_ci}
6668c2ecf20Sopenharmony_ci
6678c2ecf20Sopenharmony_cistatic inline void
6688c2ecf20Sopenharmony_citls_offload_rx_resync_async_request_end(struct sock *sk, __be32 seq)
6698c2ecf20Sopenharmony_ci{
6708c2ecf20Sopenharmony_ci	struct tls_context *tls_ctx = tls_get_ctx(sk);
6718c2ecf20Sopenharmony_ci	struct tls_offload_context_rx *rx_ctx = tls_offload_ctx_rx(tls_ctx);
6728c2ecf20Sopenharmony_ci
6738c2ecf20Sopenharmony_ci	atomic64_set(&rx_ctx->resync_async->req,
6748c2ecf20Sopenharmony_ci		     ((u64)ntohl(seq) << 32) | RESYNC_REQ);
6758c2ecf20Sopenharmony_ci}
6768c2ecf20Sopenharmony_ci
6778c2ecf20Sopenharmony_cistatic inline void
6788c2ecf20Sopenharmony_citls_offload_rx_resync_set_type(struct sock *sk, enum tls_offload_sync_type type)
6798c2ecf20Sopenharmony_ci{
6808c2ecf20Sopenharmony_ci	struct tls_context *tls_ctx = tls_get_ctx(sk);
6818c2ecf20Sopenharmony_ci
6828c2ecf20Sopenharmony_ci	tls_offload_ctx_rx(tls_ctx)->resync_type = type;
6838c2ecf20Sopenharmony_ci}
6848c2ecf20Sopenharmony_ci
6858c2ecf20Sopenharmony_ci/* Driver's seq tracking has to be disabled until resync succeeded */
6868c2ecf20Sopenharmony_cistatic inline bool tls_offload_tx_resync_pending(struct sock *sk)
6878c2ecf20Sopenharmony_ci{
6888c2ecf20Sopenharmony_ci	struct tls_context *tls_ctx = tls_get_ctx(sk);
6898c2ecf20Sopenharmony_ci	bool ret;
6908c2ecf20Sopenharmony_ci
6918c2ecf20Sopenharmony_ci	ret = test_bit(TLS_TX_SYNC_SCHED, &tls_ctx->flags);
6928c2ecf20Sopenharmony_ci	smp_mb__after_atomic();
6938c2ecf20Sopenharmony_ci	return ret;
6948c2ecf20Sopenharmony_ci}
6958c2ecf20Sopenharmony_ci
6968c2ecf20Sopenharmony_ciint __net_init tls_proc_init(struct net *net);
6978c2ecf20Sopenharmony_civoid __net_exit tls_proc_fini(struct net *net);
6988c2ecf20Sopenharmony_ci
6998c2ecf20Sopenharmony_ciint tls_proccess_cmsg(struct sock *sk, struct msghdr *msg,
7008c2ecf20Sopenharmony_ci		      unsigned char *record_type);
7018c2ecf20Sopenharmony_ciint decrypt_skb(struct sock *sk, struct sk_buff *skb,
7028c2ecf20Sopenharmony_ci		struct scatterlist *sgout);
7038c2ecf20Sopenharmony_cistruct sk_buff *tls_encrypt_skb(struct sk_buff *skb);
7048c2ecf20Sopenharmony_ci
7058c2ecf20Sopenharmony_ciint tls_sw_fallback_init(struct sock *sk,
7068c2ecf20Sopenharmony_ci			 struct tls_offload_context_tx *offload_ctx,
7078c2ecf20Sopenharmony_ci			 struct tls_crypto_info *crypto_info);
7088c2ecf20Sopenharmony_ci
7098c2ecf20Sopenharmony_ci#ifdef CONFIG_TLS_DEVICE
7108c2ecf20Sopenharmony_ciint tls_device_init(void);
7118c2ecf20Sopenharmony_civoid tls_device_cleanup(void);
7128c2ecf20Sopenharmony_civoid tls_device_sk_destruct(struct sock *sk);
7138c2ecf20Sopenharmony_ciint tls_set_device_offload(struct sock *sk, struct tls_context *ctx);
7148c2ecf20Sopenharmony_civoid tls_device_free_resources_tx(struct sock *sk);
7158c2ecf20Sopenharmony_ciint tls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx);
7168c2ecf20Sopenharmony_civoid tls_device_offload_cleanup_rx(struct sock *sk);
7178c2ecf20Sopenharmony_civoid tls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq);
7188c2ecf20Sopenharmony_civoid tls_offload_tx_resync_request(struct sock *sk, u32 got_seq, u32 exp_seq);
7198c2ecf20Sopenharmony_ciint tls_device_decrypted(struct sock *sk, struct tls_context *tls_ctx,
7208c2ecf20Sopenharmony_ci			 struct sk_buff *skb, struct strp_msg *rxm);
7218c2ecf20Sopenharmony_ci
7228c2ecf20Sopenharmony_cistatic inline bool tls_is_sk_rx_device_offloaded(struct sock *sk)
7238c2ecf20Sopenharmony_ci{
7248c2ecf20Sopenharmony_ci	if (!sk_fullsock(sk) ||
7258c2ecf20Sopenharmony_ci	    smp_load_acquire(&sk->sk_destruct) != tls_device_sk_destruct)
7268c2ecf20Sopenharmony_ci		return false;
7278c2ecf20Sopenharmony_ci	return tls_get_ctx(sk)->rx_conf == TLS_HW;
7288c2ecf20Sopenharmony_ci}
7298c2ecf20Sopenharmony_ci#else
7308c2ecf20Sopenharmony_cistatic inline int tls_device_init(void) { return 0; }
7318c2ecf20Sopenharmony_cistatic inline void tls_device_cleanup(void) {}
7328c2ecf20Sopenharmony_ci
7338c2ecf20Sopenharmony_cistatic inline int
7348c2ecf20Sopenharmony_citls_set_device_offload(struct sock *sk, struct tls_context *ctx)
7358c2ecf20Sopenharmony_ci{
7368c2ecf20Sopenharmony_ci	return -EOPNOTSUPP;
7378c2ecf20Sopenharmony_ci}
7388c2ecf20Sopenharmony_ci
7398c2ecf20Sopenharmony_cistatic inline void tls_device_free_resources_tx(struct sock *sk) {}
7408c2ecf20Sopenharmony_ci
7418c2ecf20Sopenharmony_cistatic inline int
7428c2ecf20Sopenharmony_citls_set_device_offload_rx(struct sock *sk, struct tls_context *ctx)
7438c2ecf20Sopenharmony_ci{
7448c2ecf20Sopenharmony_ci	return -EOPNOTSUPP;
7458c2ecf20Sopenharmony_ci}
7468c2ecf20Sopenharmony_ci
7478c2ecf20Sopenharmony_cistatic inline void tls_device_offload_cleanup_rx(struct sock *sk) {}
7488c2ecf20Sopenharmony_cistatic inline void
7498c2ecf20Sopenharmony_citls_device_rx_resync_new_rec(struct sock *sk, u32 rcd_len, u32 seq) {}
7508c2ecf20Sopenharmony_ci
7518c2ecf20Sopenharmony_cistatic inline int
7528c2ecf20Sopenharmony_citls_device_decrypted(struct sock *sk, struct tls_context *tls_ctx,
7538c2ecf20Sopenharmony_ci		     struct sk_buff *skb, struct strp_msg *rxm)
7548c2ecf20Sopenharmony_ci{
7558c2ecf20Sopenharmony_ci	return 0;
7568c2ecf20Sopenharmony_ci}
7578c2ecf20Sopenharmony_ci#endif
7588c2ecf20Sopenharmony_ci#endif /* _TLS_OFFLOAD_H */
759