1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2 /* Copyright (c) 2020, Mellanox Technologies inc. All rights reserved. */
3 
4 #include "en_accel/ktls_txrx.h"
5 #include "en_accel/ktls_utils.h"
6 
7 enum {
8 	MLX5E_STATIC_PARAMS_CONTEXT_TLS_1_2 = 0x2,
9 };
10 
11 enum {
12 	MLX5E_ENCRYPTION_STANDARD_TLS = 0x1,
13 };
14 
15 #define EXTRACT_INFO_FIELDS do { \
16 	salt    = info->salt;    \
17 	rec_seq = info->rec_seq; \
18 	salt_sz    = sizeof(info->salt);    \
19 	rec_seq_sz = sizeof(info->rec_seq); \
20 } while (0)
21 
22 static void
fill_static_params(struct mlx5_wqe_tls_static_params_seg * params,union mlx5e_crypto_info * crypto_info,u32 key_id,u32 resync_tcp_sn)23 fill_static_params(struct mlx5_wqe_tls_static_params_seg *params,
24 		   union mlx5e_crypto_info *crypto_info,
25 		   u32 key_id, u32 resync_tcp_sn)
26 {
27 	char *initial_rn, *gcm_iv;
28 	u16 salt_sz, rec_seq_sz;
29 	char *salt, *rec_seq;
30 	u8 tls_version;
31 	u8 *ctx;
32 
33 	ctx = params->ctx;
34 
35 	switch (crypto_info->crypto_info.cipher_type) {
36 	case TLS_CIPHER_AES_GCM_128: {
37 		struct tls12_crypto_info_aes_gcm_128 *info =
38 			&crypto_info->crypto_info_128;
39 
40 		EXTRACT_INFO_FIELDS;
41 		break;
42 	}
43 	case TLS_CIPHER_AES_GCM_256: {
44 		struct tls12_crypto_info_aes_gcm_256 *info =
45 			&crypto_info->crypto_info_256;
46 
47 		EXTRACT_INFO_FIELDS;
48 		break;
49 	}
50 	default:
51 		WARN_ONCE(1, "Unsupported cipher type %u\n",
52 			  crypto_info->crypto_info.cipher_type);
53 		return;
54 	}
55 
56 	gcm_iv      = MLX5_ADDR_OF(tls_static_params, ctx, gcm_iv);
57 	initial_rn  = MLX5_ADDR_OF(tls_static_params, ctx, initial_record_number);
58 
59 	memcpy(gcm_iv,      salt,    salt_sz);
60 	memcpy(initial_rn,  rec_seq, rec_seq_sz);
61 
62 	tls_version = MLX5E_STATIC_PARAMS_CONTEXT_TLS_1_2;
63 
64 	MLX5_SET(tls_static_params, ctx, tls_version, tls_version);
65 	MLX5_SET(tls_static_params, ctx, const_1, 1);
66 	MLX5_SET(tls_static_params, ctx, const_2, 2);
67 	MLX5_SET(tls_static_params, ctx, encryption_standard,
68 		 MLX5E_ENCRYPTION_STANDARD_TLS);
69 	MLX5_SET(tls_static_params, ctx, resync_tcp_sn, resync_tcp_sn);
70 	MLX5_SET(tls_static_params, ctx, dek_index, key_id);
71 }
72 
73 void
mlx5e_ktls_build_static_params(struct mlx5e_set_tls_static_params_wqe * wqe,u16 pc,u32 sqn,union mlx5e_crypto_info * crypto_info,u32 tis_tir_num,u32 key_id,u32 resync_tcp_sn,bool fence,enum tls_offload_ctx_dir direction)74 mlx5e_ktls_build_static_params(struct mlx5e_set_tls_static_params_wqe *wqe,
75 			       u16 pc, u32 sqn,
76 			       union mlx5e_crypto_info *crypto_info,
77 			       u32 tis_tir_num, u32 key_id, u32 resync_tcp_sn,
78 			       bool fence, enum tls_offload_ctx_dir direction)
79 {
80 	struct mlx5_wqe_umr_ctrl_seg *ucseg = &wqe->uctrl;
81 	struct mlx5_wqe_ctrl_seg     *cseg  = &wqe->ctrl;
82 	u8 opmod = direction == TLS_OFFLOAD_CTX_DIR_TX ?
83 		MLX5_OPC_MOD_TLS_TIS_STATIC_PARAMS :
84 		MLX5_OPC_MOD_TLS_TIR_STATIC_PARAMS;
85 
86 #define STATIC_PARAMS_DS_CNT DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS)
87 
88 	cseg->opmod_idx_opcode = cpu_to_be32((pc << 8) | MLX5_OPCODE_UMR | (opmod << 24));
89 	cseg->qpn_ds           = cpu_to_be32((sqn << MLX5_WQE_CTRL_QPN_SHIFT) |
90 					     STATIC_PARAMS_DS_CNT);
91 	cseg->fm_ce_se         = fence ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
92 	cseg->tis_tir_num      = cpu_to_be32(tis_tir_num << 8);
93 
94 	ucseg->flags = MLX5_UMR_INLINE;
95 	ucseg->bsf_octowords = cpu_to_be16(MLX5_ST_SZ_BYTES(tls_static_params) / 16);
96 
97 	fill_static_params(&wqe->params, crypto_info, key_id, resync_tcp_sn);
98 }
99 
100 static void
fill_progress_params(struct mlx5_wqe_tls_progress_params_seg * params,u32 tis_tir_num,u32 next_record_tcp_sn)101 fill_progress_params(struct mlx5_wqe_tls_progress_params_seg *params, u32 tis_tir_num,
102 		     u32 next_record_tcp_sn)
103 {
104 	u8 *ctx = params->ctx;
105 
106 	params->tis_tir_num = cpu_to_be32(tis_tir_num);
107 
108 	MLX5_SET(tls_progress_params, ctx, next_record_tcp_sn,
109 		 next_record_tcp_sn);
110 	MLX5_SET(tls_progress_params, ctx, record_tracker_state,
111 		 MLX5E_TLS_PROGRESS_PARAMS_RECORD_TRACKER_STATE_START);
112 	MLX5_SET(tls_progress_params, ctx, auth_state,
113 		 MLX5E_TLS_PROGRESS_PARAMS_AUTH_STATE_NO_OFFLOAD);
114 }
115 
116 void
mlx5e_ktls_build_progress_params(struct mlx5e_set_tls_progress_params_wqe * wqe,u16 pc,u32 sqn,u32 tis_tir_num,bool fence,u32 next_record_tcp_sn,enum tls_offload_ctx_dir direction)117 mlx5e_ktls_build_progress_params(struct mlx5e_set_tls_progress_params_wqe *wqe,
118 				 u16 pc, u32 sqn,
119 				 u32 tis_tir_num, bool fence,
120 				 u32 next_record_tcp_sn,
121 				 enum tls_offload_ctx_dir direction)
122 {
123 	struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
124 	u8 opmod = direction == TLS_OFFLOAD_CTX_DIR_TX ?
125 		MLX5_OPC_MOD_TLS_TIS_PROGRESS_PARAMS :
126 		MLX5_OPC_MOD_TLS_TIR_PROGRESS_PARAMS;
127 
128 #define PROGRESS_PARAMS_DS_CNT DIV_ROUND_UP(sizeof(*wqe), MLX5_SEND_WQE_DS)
129 
130 	cseg->opmod_idx_opcode =
131 		cpu_to_be32((pc << 8) | MLX5_OPCODE_SET_PSV | (opmod << 24));
132 	cseg->qpn_ds           = cpu_to_be32((sqn << MLX5_WQE_CTRL_QPN_SHIFT) |
133 					     PROGRESS_PARAMS_DS_CNT);
134 	cseg->fm_ce_se         = fence ? MLX5_FENCE_MODE_INITIATOR_SMALL : 0;
135 
136 	fill_progress_params(&wqe->params, tis_tir_num, next_record_tcp_sn);
137 }
138 
139