Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
3 : : */
4 : :
5 : : #include <rte_malloc.h>
6 : : #include <rte_bitmap.h>
7 : :
8 : : #include "sxe2_ethdev.h"
9 : : #include "sxe2_security.h"
10 : : #include "sxe2_ipsec.h"
11 : : #include "sxe2_cmd_chnl.h"
12 : : #include "sxe2_common_log.h"
13 : :
14 : 0 : bool sxe2_ipsec_supported(struct sxe2_adapter *adapter)
15 : : {
16 : 0 : uint64_t cap = adapter->cap_flags;
17 : :
18 : 0 : return !!(cap & SXE2_DEV_CAPS_OFFLOAD_IPSEC);
19 : : }
20 : :
21 : 0 : bool sxe2_ipsec_valid_tx_offloads(uint64_t offloads)
22 : : {
23 : 0 : bool ret = true;
24 : 0 : uint64_t tso_features = 0;
25 : 0 : uint64_t cksum_features = 0;
26 : :
27 [ # # ]: 0 : if (offloads & RTE_ETH_TX_OFFLOAD_SECURITY) {
28 : 0 : tso_features = RTE_ETH_TX_OFFLOAD_TCP_TSO |
29 : : RTE_ETH_TX_OFFLOAD_UDP_TSO |
30 : : RTE_ETH_TX_OFFLOAD_VXLAN_TNL_TSO |
31 : : RTE_ETH_TX_OFFLOAD_GRE_TNL_TSO |
32 : : RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO |
33 : : RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
34 [ # # ]: 0 : if (offloads & tso_features) {
35 : 0 : PMD_LOG_ERR(DRV, "Security offload is not compatible with TSO offload.");
36 : 0 : ret = false;
37 : 0 : goto l_end;
38 : : }
39 : :
40 : 0 : cksum_features = RTE_ETH_TX_OFFLOAD_IPV4_CKSUM |
41 : : RTE_ETH_TX_OFFLOAD_UDP_CKSUM |
42 : : RTE_ETH_TX_OFFLOAD_TCP_CKSUM |
43 : : RTE_ETH_TX_OFFLOAD_SCTP_CKSUM |
44 : : RTE_ETH_TX_OFFLOAD_OUTER_IPV4_CKSUM |
45 : : RTE_ETH_TX_OFFLOAD_OUTER_UDP_CKSUM;
46 [ # # ]: 0 : if (offloads & cksum_features) {
47 : 0 : PMD_LOG_ERR(DRV, "Security offload is not compatible with checksum offload.");
48 : 0 : ret = false;
49 : 0 : goto l_end;
50 : : }
51 : :
52 [ # # ]: 0 : if (offloads & (RTE_ETH_TX_OFFLOAD_VLAN_INSERT | RTE_ETH_TX_OFFLOAD_QINQ_INSERT)) {
53 : 0 : PMD_LOG_ERR(DRV, "Security offload is not compatible with vlan offload.");
54 : 0 : ret = false;
55 : 0 : goto l_end;
56 : : }
57 : : }
58 : :
59 : 0 : l_end:
60 : 0 : return ret;
61 : : }
62 : :
63 : 0 : bool sxe2_ipsec_valid_rx_offloads(uint64_t offloads)
64 : : {
65 : 0 : bool ret = true;
66 : :
67 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_SECURITY) {
68 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) {
69 : 0 : PMD_LOG_ERR(DRV, "Security offload is not compatible with LRO offload.");
70 : 0 : ret = false;
71 : 0 : goto l_end;
72 : : }
73 : :
74 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_CHECKSUM) {
75 : 0 : PMD_LOG_ERR(DRV, "Security offload is not compatible with checksum offload.");
76 : 0 : ret = false;
77 : 0 : goto l_end;
78 : : }
79 : :
80 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_KEEP_CRC) {
81 : 0 : PMD_LOG_ERR(DRV, "Security offload is not compatible with keep CRC offload.");
82 : 0 : ret = false;
83 : 0 : goto l_end;
84 : : }
85 : :
86 [ # # ]: 0 : if (offloads & RTE_ETH_RX_OFFLOAD_VLAN) {
87 : 0 : PMD_LOG_ERR(DRV, "Security offload is not compatible with vlan offload.");
88 : 0 : ret = false;
89 : 0 : goto l_end;
90 : : }
91 : : }
92 : :
93 : 0 : l_end:
94 : 0 : return ret;
95 : : }
96 : :
97 : 0 : static int32_t sxe2_ipsec_bitmap_mem_init(struct rte_bitmap **d_bmp, void **d_mem, uint32_t bits)
98 : : {
99 : 0 : struct rte_bitmap *bmp = NULL;
100 : 0 : uint32_t bmp_size = 0;
101 : 0 : void *mem = NULL;
102 : 0 : int32_t ret = -1;
103 : :
104 : 0 : bmp_size = rte_bitmap_get_memory_footprint(bits);
105 : :
106 : 0 : mem = rte_zmalloc("ipsec bitmap", bmp_size, RTE_CACHE_LINE_SIZE);
107 [ # # ]: 0 : if (mem == NULL) {
108 : 0 : PMD_LOG_ERR(DRV, "Alloc ipsec bitmap memory failed.");
109 : 0 : ret = -ENOMEM;
110 : 0 : goto l_end;
111 : : }
112 : :
113 : 0 : bmp = rte_bitmap_init(bits, mem, bmp_size);
114 [ # # ]: 0 : if (bmp == NULL) {
115 : 0 : PMD_LOG_ERR(DRV, "Failed to init ipsec bitmap.");
116 : 0 : rte_free(mem);
117 : 0 : ret = -ENOMEM;
118 : 0 : goto l_end;
119 : : }
120 : :
121 : 0 : *d_bmp = bmp;
122 : 0 : *d_mem = mem;
123 : :
124 : 0 : ret = 0;
125 : :
126 : 0 : l_end:
127 : 0 : return ret;
128 : : }
129 : :
130 : 0 : static int32_t sxe2_ipsec_bitmap_init(struct sxe2_security_ctx *sxe2_sctx)
131 : : {
132 : 0 : int32_t ret = -1;
133 : :
134 : 0 : ret = sxe2_ipsec_bitmap_mem_init(&sxe2_sctx->ipsec_ctx.bmp.tx_sa_bmp,
135 : 0 : &sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem, sxe2_sctx->ipsec_ctx.max_tx_sa);
136 [ # # ]: 0 : if (ret)
137 : 0 : goto l_end;
138 : :
139 : 0 : ret = sxe2_ipsec_bitmap_mem_init(&sxe2_sctx->ipsec_ctx.bmp.rx_sa_bmp,
140 : 0 : &sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem, sxe2_sctx->ipsec_ctx.max_rx_sa);
141 [ # # ]: 0 : if (ret) {
142 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem);
143 : 0 : sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem = NULL;
144 : 0 : goto l_end;
145 : : }
146 : :
147 : 0 : ret = sxe2_ipsec_bitmap_mem_init(&sxe2_sctx->ipsec_ctx.bmp.rx_tcam_bmp,
148 : 0 : &sxe2_sctx->ipsec_ctx.bmp.rx_tcam_mem, sxe2_sctx->ipsec_ctx.max_tcam);
149 [ # # ]: 0 : if (ret) {
150 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem);
151 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem);
152 : 0 : sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem = NULL;
153 : 0 : sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem = NULL;
154 : 0 : goto l_end;
155 : : }
156 : :
157 : 0 : ret = sxe2_ipsec_bitmap_mem_init(&sxe2_sctx->ipsec_ctx.bmp.rx_udp_bmp,
158 : 0 : &sxe2_sctx->ipsec_ctx.bmp.rx_udp_mem, sxe2_sctx->ipsec_ctx.max_udp_group);
159 [ # # ]: 0 : if (ret) {
160 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem);
161 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem);
162 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.rx_tcam_mem);
163 : 0 : sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem = NULL;
164 : 0 : sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem = NULL;
165 : 0 : sxe2_sctx->ipsec_ctx.bmp.rx_tcam_mem = NULL;
166 : 0 : goto l_end;
167 : : }
168 : :
169 : 0 : l_end:
170 : 0 : return ret;
171 : : }
172 : :
173 : 0 : static uint16_t sxe2_ipsec_id_alloc(struct rte_bitmap *bmp, uint16_t bits)
174 : : {
175 : 0 : uint16_t i = 0;
176 : 0 : uint16_t index = 0XFFFF;
177 : :
178 [ # # ]: 0 : for (i = 0; i < bits; i++) {
179 [ # # ]: 0 : if (!rte_bitmap_get(bmp, i)) {
180 : 0 : index = i;
181 : 0 : rte_bitmap_set(bmp, i);
182 : 0 : break;
183 : : }
184 : : }
185 : :
186 : 0 : return index;
187 : : }
188 : :
189 : 0 : static void sxe2_ipsec_id_free(struct rte_bitmap *bmp, uint16_t pos)
190 : : {
191 : 0 : rte_bitmap_clear(bmp, pos);
192 : 0 : }
193 : :
194 : : static struct rte_cryptodev_symmetric_capability *
195 : 0 : sxe2_ipsec_cipher_cap_get(struct rte_cryptodev_capabilities *crypto_cap,
196 : : enum rte_crypto_cipher_algorithm algo)
197 : : {
198 : 0 : struct rte_cryptodev_symmetric_capability *capability = NULL;
199 : 0 : uint8_t index = 0;
200 : :
201 [ # # ]: 0 : for (index = 0; index < SXE2_IPSEC_CAP_MAX; index++) {
202 [ # # ]: 0 : if (crypto_cap[index].sym.xform_type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
203 [ # # ]: 0 : crypto_cap[index].sym.cipher.algo == algo) {
204 : 0 : capability = &crypto_cap[index].sym;
205 : 0 : goto l_end;
206 : : }
207 : : }
208 : :
209 : 0 : l_end:
210 : 0 : return capability;
211 : : }
212 : :
213 : : static struct rte_cryptodev_symmetric_capability *
214 : 0 : sxe2_ipsec_auth_cap_get(struct rte_cryptodev_capabilities *crypto_cap,
215 : : enum rte_crypto_auth_algorithm algo)
216 : : {
217 : 0 : struct rte_cryptodev_symmetric_capability *capability = NULL;
218 : 0 : uint8_t index = 0;
219 : :
220 [ # # ]: 0 : for (index = 0; index < SXE2_IPSEC_CAP_MAX; index++) {
221 [ # # ]: 0 : if (crypto_cap[index].sym.xform_type == RTE_CRYPTO_SYM_XFORM_AUTH &&
222 [ # # ]: 0 : crypto_cap[index].sym.auth.algo == algo) {
223 : 0 : capability = &crypto_cap[index].sym;
224 : 0 : goto l_end;
225 : : }
226 : : }
227 : :
228 : 0 : l_end:
229 : 0 : return capability;
230 : : }
231 : :
232 : 0 : static bool sxe2_security_valid_key(uint16_t src_key, uint16_t max_key,
233 : : uint16_t min_key, uint16_t increment)
234 : : {
235 : 0 : bool is_valid = false;
236 : :
237 : 0 : if (src_key > SXE2_IPSEC_MAX_KEY_LEN) {
238 : 0 : is_valid = false;
239 : 0 : goto l_end;
240 : : }
241 : :
242 [ # # # # ]: 0 : if (src_key < min_key || src_key > max_key) {
243 : 0 : is_valid = false;
244 : 0 : goto l_end;
245 : : }
246 : :
247 [ # # # # ]: 0 : if (increment == 0) {
248 : 0 : is_valid = true;
249 : 0 : goto l_end;
250 : : }
251 : :
252 [ # # # # ]: 0 : if ((uint16_t)(src_key - min_key) % increment) {
253 : 0 : is_valid = false;
254 : 0 : goto l_end;
255 : : }
256 : :
257 : : is_valid = true;
258 : :
259 : : l_end:
260 : 0 : return is_valid;
261 : : }
262 : :
263 : : static int32_t
264 : 0 : sxe2_ipsec_valid_cipher(enum rte_crypto_cipher_operation cipher_op,
265 : : struct rte_cryptodev_capabilities *crypto_cap,
266 : : struct rte_crypto_sym_xform *xform)
267 : : {
268 : 0 : const struct rte_cryptodev_symmetric_capability *capability = NULL;
269 : 0 : uint16_t src_key = 0;
270 : 0 : uint16_t max_key = 0;
271 : 0 : uint16_t min_key = 0;
272 : 0 : uint16_t increment = 0;
273 : 0 : int32_t ret = -1;
274 : :
275 [ # # ]: 0 : if (xform->cipher.op != cipher_op) {
276 : 0 : PMD_LOG_ERR(DRV, "Invalid cipher direction specified");
277 : 0 : ret = -EINVAL;
278 : 0 : goto l_end;
279 : : }
280 : :
281 : 0 : capability = sxe2_ipsec_cipher_cap_get(crypto_cap, xform->cipher.algo);
282 [ # # ]: 0 : if (!capability) {
283 : 0 : PMD_LOG_ERR(DRV, "Invalid cipher algo specified");
284 : 0 : ret = -EINVAL;
285 : 0 : goto l_end;
286 : : }
287 : :
288 : 0 : src_key = xform->cipher.key.length;
289 : 0 : min_key = capability->cipher.key_size.min;
290 : 0 : max_key = capability->cipher.key_size.max;
291 : 0 : increment = capability->cipher.key_size.increment;
292 [ # # ]: 0 : if (!sxe2_security_valid_key(src_key, max_key, min_key, increment)) {
293 : 0 : PMD_LOG_ERR(DRV, "Invalid cipher key size specified");
294 : 0 : ret = -EINVAL;
295 : 0 : goto l_end;
296 : : }
297 : :
298 : : ret = 0;
299 : :
300 : 0 : l_end:
301 : 0 : return ret;
302 : : }
303 : :
304 : : static int32_t
305 : 0 : sxe2_ipsec_valid_auth(enum rte_crypto_auth_operation auth_op,
306 : : struct rte_cryptodev_capabilities *crypto_cap,
307 : : struct rte_crypto_sym_xform *xform)
308 : : {
309 : 0 : const struct rte_cryptodev_symmetric_capability *capability = NULL;
310 : 0 : uint16_t src_key = 0;
311 : 0 : uint16_t max_key = 0;
312 : 0 : uint16_t min_key = 0;
313 : 0 : uint16_t increment = 0;
314 : 0 : int32_t ret = -1;
315 : :
316 [ # # ]: 0 : if (xform->auth.op != auth_op) {
317 : 0 : PMD_LOG_ERR(DRV, "Invalid auth direction specified");
318 : 0 : ret = -EINVAL;
319 : 0 : goto l_end;
320 : : }
321 : :
322 : 0 : capability = sxe2_ipsec_auth_cap_get(crypto_cap, xform->auth.algo);
323 [ # # ]: 0 : if (!capability) {
324 : 0 : PMD_LOG_ERR(DRV, "Invalid auth algo specified");
325 : 0 : ret = -EINVAL;
326 : 0 : goto l_end;
327 : : }
328 : :
329 : 0 : src_key = xform->auth.key.length;
330 : 0 : min_key = capability->auth.key_size.min;
331 : 0 : max_key = capability->auth.key_size.max;
332 : 0 : increment = capability->auth.key_size.increment;
333 [ # # ]: 0 : if (!sxe2_security_valid_key(src_key, max_key, min_key, increment)) {
334 : 0 : PMD_LOG_ERR(DRV, "Invalid auth key size specified");
335 : 0 : ret = -EINVAL;
336 : 0 : goto l_end;
337 : : }
338 : :
339 : : ret = 0;
340 : :
341 : 0 : l_end:
342 : 0 : return ret;
343 : : }
344 : :
345 : : static bool
346 : 0 : sxe2_ipsec_valid_algo(enum rte_crypto_auth_algorithm auth_algo,
347 : : enum rte_crypto_cipher_algorithm cipher_algo)
348 : : {
349 : 0 : bool ret = false;
350 : :
351 : 0 : if ((cipher_algo == SXE2_RTE_CRYPTO_CIPHER_AES_CBC &&
352 : 0 : auth_algo == SXE2_RTE_CRYPTO_AUTH_SHA256_HMAC) ||
353 : 0 : (cipher_algo == SXE2_RTE_RTE_CRYPTO_CIPHER_SM4_CBC &&
354 [ # # # # ]: 0 : auth_algo == SXE2_RTE_CRYPTO_AUTH_SM3_HMAC)) {
355 : 0 : ret = true;
356 : 0 : goto l_end;
357 : : }
358 : :
359 : 0 : l_end:
360 : 0 : return ret;
361 : : }
362 : :
363 : : static enum sxe2_ipsec_algorithm
364 : 0 : sxe2_ipsec_algo_gen(enum rte_crypto_cipher_algorithm cipher_algo)
365 : : {
366 : 0 : enum sxe2_ipsec_algorithm algo = SXE2_IPSEC_ALGO_INVALID;
367 : :
368 : 0 : if (cipher_algo == SXE2_RTE_CRYPTO_CIPHER_AES_CBC)
369 : : algo = SXE2_IPSEC_ALGO_AES_CBC_AND_SHA256_128_HMAC;
370 [ # # ]: 0 : else if (cipher_algo == SXE2_RTE_RTE_CRYPTO_CIPHER_SM4_CBC)
371 : 0 : algo = SXE2_IPSEC_ALGO_SM4_CBC_AND_SM3_96_HMAC;
372 : :
373 : 0 : return algo;
374 : : }
375 : :
376 : : static int32_t
377 : 0 : sxe2_ipsec_valid_xform(struct sxe2_security_ctx *sxe2_sctx,
378 : : struct rte_security_session_conf *conf)
379 : : {
380 : 0 : struct rte_crypto_sym_xform *xform = NULL;
381 : 0 : struct rte_cryptodev_capabilities *crypto_cap =
382 : : sxe2_sctx->sxe2_capabilities[SXE2_SECURITY_PROTOCOL_IPSEC].crypto_capabilities;
383 : 0 : enum rte_crypto_auth_algorithm auth_algo = RTE_CRYPTO_AUTH_NULL;
384 : 0 : enum rte_crypto_cipher_algorithm cipher_algo = RTE_CRYPTO_CIPHER_NULL;
385 : 0 : int32_t ret = -1;
386 : :
387 [ # # ]: 0 : if (conf->ipsec.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
388 [ # # ]: 0 : conf->crypto_xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
389 : 0 : xform = conf->crypto_xform;
390 : 0 : cipher_algo = xform->cipher.algo;
391 : 0 : ret = sxe2_ipsec_valid_cipher(RTE_CRYPTO_CIPHER_OP_ENCRYPT,
392 : : crypto_cap, xform);
393 [ # # ]: 0 : if (ret)
394 : 0 : goto l_end;
395 : :
396 [ # # ]: 0 : if (conf->crypto_xform->next) {
397 [ # # ]: 0 : if (conf->crypto_xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
398 : 0 : auth_algo = conf->crypto_xform->next->auth.algo;
399 [ # # ]: 0 : if (!sxe2_ipsec_valid_algo(auth_algo, cipher_algo)) {
400 : 0 : PMD_LOG_ERR(DRV, "Invalid algo group.");
401 : 0 : ret = -EINVAL;
402 : 0 : goto l_end;
403 : : }
404 : 0 : xform = conf->crypto_xform->next;
405 : 0 : ret = sxe2_ipsec_valid_auth(RTE_CRYPTO_AUTH_OP_GENERATE,
406 : : crypto_cap, xform);
407 [ # # ]: 0 : if (ret)
408 : 0 : goto l_end;
409 : : } else {
410 : 0 : PMD_LOG_ERR(DRV, "Encrypt direction next xform only verify.");
411 : 0 : ret = -EINVAL;
412 : 0 : goto l_end;
413 : : }
414 : : }
415 [ # # ]: 0 : } else if (conf->ipsec.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
416 [ # # ]: 0 : conf->crypto_xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
417 : 0 : xform = conf->crypto_xform;
418 : 0 : ret = sxe2_ipsec_valid_cipher(RTE_CRYPTO_CIPHER_OP_DECRYPT,
419 : : crypto_cap, xform);
420 [ # # ]: 0 : if (ret)
421 : 0 : goto l_end;
422 : :
423 [ # # ]: 0 : } else if (conf->ipsec.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
424 [ # # ]: 0 : conf->crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
425 : 0 : xform = conf->crypto_xform;
426 : 0 : ret = sxe2_ipsec_valid_auth(RTE_CRYPTO_AUTH_OP_VERIFY, crypto_cap, xform);
427 [ # # ]: 0 : if (ret)
428 : 0 : goto l_end;
429 : :
430 [ # # ]: 0 : if (conf->crypto_xform->next &&
431 [ # # ]: 0 : conf->crypto_xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
432 : 0 : auth_algo = conf->crypto_xform->auth.algo;
433 : 0 : cipher_algo = conf->crypto_xform->next->cipher.algo;
434 [ # # ]: 0 : if (!sxe2_ipsec_valid_algo(auth_algo, cipher_algo)) {
435 : 0 : PMD_LOG_ERR(DRV, "Invalid algo group.");
436 : 0 : ret = -EINVAL;
437 : 0 : goto l_end;
438 : : }
439 : 0 : xform = conf->crypto_xform->next;
440 : 0 : ret = sxe2_ipsec_valid_cipher(RTE_CRYPTO_CIPHER_OP_DECRYPT,
441 : : crypto_cap, xform);
442 [ # # ]: 0 : if (ret)
443 : 0 : goto l_end;
444 : : } else {
445 : 0 : PMD_LOG_ERR(DRV, "Not support decrypt direction only verify, but not decrypt.");
446 : 0 : ret = -EINVAL;
447 : 0 : goto l_end;
448 : : }
449 : : } else {
450 : 0 : PMD_LOG_ERR(DRV, "Encrypt/decrypt xform invalid.");
451 : 0 : ret = -EINVAL;
452 : 0 : goto l_end;
453 : : }
454 : :
455 : : ret = 0;
456 : :
457 : 0 : l_end:
458 : 0 : return ret;
459 : : }
460 : :
461 : : static int32_t
462 : 0 : sxe2_ipsec_valid_udp(struct rte_security_session_conf *conf)
463 : : {
464 : 0 : int32_t ret = -1;
465 : 0 : uint16_t sport = conf->ipsec.udp.sport;
466 : 0 : uint16_t dport = conf->ipsec.udp.dport;
467 : :
468 [ # # ]: 0 : if (conf->ipsec.options.udp_encap == 0) {
469 : 0 : ret = 0;
470 : 0 : goto l_end;
471 : : }
472 : :
473 [ # # ]: 0 : if (sport == 0 && dport == 0) {
474 : 0 : PMD_LOG_ERR(DRV, "Invalid udp port, cannot be zero.");
475 : 0 : ret = -1;
476 : 0 : goto l_end;
477 : : }
478 : :
479 [ # # # # ]: 0 : if (sport != 0 && dport != 0 && sport != dport) {
480 : 0 : PMD_LOG_ERR(DRV, "Invalid udp port, if sport and dport is not zero, must be equal.");
481 : 0 : ret = -1;
482 : 0 : goto l_end;
483 : : }
484 : :
485 : : ret = 0;
486 : :
487 : 0 : l_end:
488 : 0 : return ret;
489 : : }
490 : :
491 : : static int32_t
492 : 0 : sxe2_ipsec_session_conf_valid(struct sxe2_security_ctx *sxe2_sctx,
493 : : struct rte_security_session_conf *conf)
494 : : {
495 : 0 : int32_t ret = -1;
496 : :
497 [ # # ]: 0 : if (sxe2_sctx == NULL) {
498 : 0 : PMD_LOG_ERR(DRV, "Invalid security ctx.");
499 : 0 : ret = -EINVAL;
500 : 0 : goto l_end;
501 : : }
502 : :
503 : 0 : if (conf->action_type !=
504 [ # # ]: 0 : sxe2_sctx->sxe2_capabilities[SXE2_SECURITY_PROTOCOL_IPSEC].action) {
505 : 0 : PMD_LOG_ERR(DRV, "Invalid action specified");
506 : 0 : ret = -EINVAL;
507 : 0 : goto l_end;
508 : : }
509 : :
510 : 0 : if (conf->ipsec.mode !=
511 [ # # ]: 0 : sxe2_sctx->sxe2_capabilities[SXE2_SECURITY_PROTOCOL_IPSEC].ipsec.mode) {
512 : 0 : PMD_LOG_ERR(DRV, "Invalid IPsec mode specified");
513 : 0 : ret = -EINVAL;
514 : 0 : goto l_end;
515 : : }
516 : :
517 : 0 : if (conf->ipsec.proto !=
518 [ # # ]: 0 : sxe2_sctx->sxe2_capabilities[SXE2_SECURITY_PROTOCOL_IPSEC].ipsec.proto) {
519 : 0 : PMD_LOG_ERR(DRV, "Invalid IPsec protocol specified");
520 : 0 : ret = -EINVAL;
521 : 0 : goto l_end;
522 : : }
523 : :
524 [ # # ]: 0 : if (conf->ipsec.options.esn) {
525 : 0 : PMD_LOG_ERR(DRV, "Not support esn.");
526 : 0 : ret = -EINVAL;
527 : 0 : goto l_end;
528 : : }
529 : :
530 [ # # ]: 0 : if (conf->ipsec.direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
531 [ # # ]: 0 : conf->ipsec.spi == 0) {
532 : 0 : PMD_LOG_ERR(DRV, "spi cannot be zero.");
533 : 0 : ret = -EINVAL;
534 : 0 : goto l_end;
535 : : }
536 : :
537 [ # # ]: 0 : if (conf->crypto_xform == NULL) {
538 : 0 : PMD_LOG_ERR(DRV, "Invalid ipsec xform specified");
539 : 0 : ret = -EINVAL;
540 : 0 : goto l_end;
541 : : }
542 : :
543 : 0 : ret = sxe2_ipsec_valid_udp(conf);
544 [ # # ]: 0 : if (ret)
545 : 0 : goto l_end;
546 : :
547 : 0 : ret = sxe2_ipsec_valid_xform(sxe2_sctx, conf);
548 [ # # ]: 0 : if (ret)
549 : 0 : goto l_end;
550 : :
551 : 0 : l_end:
552 : 0 : return ret;
553 : : }
554 : :
555 : : static void
556 : 0 : sxe2_ipsec_session_save(struct sxe2_security_ctx *sxe2_sctx,
557 : : struct rte_security_session_conf *conf,
558 : : struct sxe2_security_session *sxe2_sess, uint16_t sa_id, uint16_t index)
559 : : {
560 : 0 : enum rte_crypto_cipher_algorithm cipher_algo = RTE_CRYPTO_CIPHER_NULL;
561 : :
562 : 0 : sxe2_sess->adapter = sxe2_sctx->adapter;
563 : 0 : sxe2_sess->direction = conf->ipsec.direction;
564 : 0 : sxe2_sess->protocol = conf->protocol;
565 : 0 : sxe2_sess->mode = conf->ipsec.mode;
566 : 0 : sxe2_sess->sa_proto = conf->ipsec.proto;
567 : 0 : sxe2_sess->sa.spi = conf->ipsec.spi;
568 : 0 : sxe2_sess->sa.hw_idx = sa_id;
569 : 0 : sxe2_sess->sa.sw_idx = index;
570 : :
571 [ # # ]: 0 : if (conf->ipsec.options.esn) {
572 : 0 : sxe2_sess->esn.enabled = true;
573 : 0 : sxe2_sess->esn.value = conf->ipsec.esn.value;
574 : : }
575 : :
576 [ # # ]: 0 : if (sxe2_sess->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
577 : 0 : sxe2_sess->type = conf->ipsec.tunnel.type;
578 : :
579 [ # # ]: 0 : if (conf->ipsec.options.udp_encap) {
580 : 0 : sxe2_sess->udp_cap.enabled = true;
581 : 0 : memcpy(&sxe2_sess->udp_cap.value, &conf->ipsec.udp,
582 : : sizeof(struct rte_security_ipsec_udp_param));
583 : : }
584 : :
585 : 0 : sxe2_sess->pkt_metadata_template.sa_idx = sa_id;
586 : 0 : sxe2_sess->pkt_metadata_template.ol_flags |= SXE2_IPSEC_OL_FLAGS_IS_TUN;
587 : 0 : sxe2_sess->pkt_metadata_template.ol_flags |= SXE2_IPSEC_OL_FLAGS_IS_ESP;
588 : :
589 [ # # ]: 0 : if (conf->ipsec.direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
590 [ # # ]: 0 : conf->crypto_xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
591 : 0 : cipher_algo = conf->crypto_xform->cipher.algo;
592 [ # # ]: 0 : sxe2_sess->pkt_metadata_template.algo = sxe2_ipsec_algo_gen(cipher_algo);
593 [ # # ]: 0 : if (conf->crypto_xform->next)
594 : 0 : sxe2_sess->pkt_metadata_template.mode = SXE2_IPSEC_MODE_ENC_AND_AUTH;
595 : : else
596 : 0 : sxe2_sess->pkt_metadata_template.mode = SXE2_IPSEC_MODE_ONLY_ENCRYPT;
597 : : }
598 : :
599 : 0 : PMD_LOG_INFO(DRV,
600 : : "Save security info to session ctx, said:%u, spi:%u, mode:%u, algo:%u",
601 : : sa_id, sxe2_sess->sa.spi,
602 : : sxe2_sess->pkt_metadata_template.mode,
603 : : sxe2_sess->pkt_metadata_template.algo);
604 : 0 : }
605 : :
606 : : static void
607 : 0 : sxe2_ipsec_tx_sa_fill(struct sxe2_ipsec_tx_sa *tx_sa,
608 : : struct rte_security_session_conf *conf)
609 : : {
610 : 0 : uint8_t *dst = NULL;
611 : 0 : uint8_t len = 0;
612 : :
613 [ # # ]: 0 : memcpy(&tx_sa->xform, &conf->ipsec, sizeof(struct rte_security_ipsec_xform));
614 : :
615 [ # # ]: 0 : if (conf->crypto_xform->next)
616 : 0 : tx_sa->mode = SXE2_IPSEC_MODE_ENC_AND_AUTH;
617 : : else
618 : 0 : tx_sa->mode = SXE2_IPSEC_MODE_ONLY_ENCRYPT;
619 : :
620 [ # # ]: 0 : if (conf->crypto_xform->cipher.algo == SXE2_RTE_RTE_CRYPTO_CIPHER_SM4_CBC)
621 : 0 : tx_sa->algo = SXE2_IPSEC_ALGO_SM4_CBC_AND_SM3_96_HMAC;
622 : : else
623 : 0 : tx_sa->algo = SXE2_IPSEC_ALGO_AES_CBC_AND_SHA256_128_HMAC;
624 : :
625 : 0 : dst = tx_sa->enc_key;
626 : 0 : len = conf->crypto_xform->cipher.key.length;
627 [ # # ]: 0 : memcpy(dst, conf->crypto_xform->cipher.key.data, len);
628 : :
629 [ # # ]: 0 : if (conf->crypto_xform->next) {
630 : 0 : dst = tx_sa->auth_key;
631 : 0 : len = conf->crypto_xform->next->auth.key.length;
632 : 0 : memcpy(dst, conf->crypto_xform->next->auth.key.data, len);
633 : : }
634 : 0 : }
635 : :
636 : : static int32_t
637 : 0 : sxe2_ipsec_tx_sa_add(struct sxe2_security_ctx *sxe2_sctx,
638 : : struct rte_security_session_conf *conf,
639 : : struct sxe2_security_session *sxe2_sess)
640 : : {
641 : 0 : struct sxe2_ipsec_tx_sa *tx_sa = NULL;
642 : 0 : struct rte_bitmap *bmp = sxe2_sctx->ipsec_ctx.bmp.tx_sa_bmp;
643 : 0 : uint16_t bits = sxe2_sctx->ipsec_ctx.max_tx_sa;
644 : 0 : uint16_t index = 0xFFFF;
645 : 0 : int32_t ret = -1;
646 : :
647 : 0 : rte_spinlock_lock(&sxe2_sctx->security_lock);
648 : 0 : index = sxe2_ipsec_id_alloc(bmp, bits);
649 : 0 : rte_spinlock_unlock(&sxe2_sctx->security_lock);
650 [ # # ]: 0 : if (index == 0xFFFF) {
651 : 0 : PMD_LOG_ERR(DRV, "Failed to allocate ipsec tx sa index.");
652 : 0 : ret = -ENOMEM;
653 : 0 : goto l_end;
654 : : }
655 : 0 : tx_sa = &sxe2_sctx->ipsec_ctx.tx_sa[index];
656 : :
657 : 0 : sxe2_ipsec_tx_sa_fill(tx_sa, conf);
658 : :
659 : 0 : ret = sxe2_drv_ipsec_txsa_add(sxe2_sctx->adapter, tx_sa);
660 [ # # ]: 0 : if (ret) {
661 : 0 : PMD_LOG_ERR(DRV, "Failed to add tx sa.");
662 : 0 : ret = -EIO;
663 : 0 : rte_spinlock_lock(&sxe2_sctx->security_lock);
664 : 0 : sxe2_ipsec_id_free(bmp, index);
665 : 0 : rte_spinlock_unlock(&sxe2_sctx->security_lock);
666 : 0 : goto l_end;
667 : : }
668 : :
669 : 0 : sxe2_ipsec_session_save(sxe2_sctx, conf, sxe2_sess, tx_sa->hw_sa_id, tx_sa->id);
670 : :
671 : 0 : PMD_LOG_INFO(DRV, "Add tx sa success, tx sa id: %u, index: %u.",
672 : : tx_sa->hw_sa_id, tx_sa->id);
673 : :
674 : 0 : l_end:
675 : 0 : return ret;
676 : : }
677 : :
678 : : static uint16_t
679 : 0 : sxe2_ipsec_tcam_id_find(struct sxe2_ipsec_rx_tcam *rx_tcam,
680 : : struct rte_security_ipsec_tunnel_param tunnel, uint16_t len)
681 : : {
682 : 0 : struct sxe2_ipsec_rx_tcam *per = NULL;
683 : 0 : uint16_t tcam_id = 0XFFFF;
684 : 0 : uint16_t i = 0;
685 : :
686 [ # # ]: 0 : for (i = 0; i < len; i++) {
687 : 0 : per = &rx_tcam[i];
688 [ # # ]: 0 : if (per->ip_addr.type == tunnel.type) {
689 [ # # ]: 0 : if (tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4 &&
690 [ # # ]: 0 : per->ip_addr.dst_ipv4 == (uint32_t)tunnel.ipv4.dst_ip.s_addr) {
691 : 0 : tcam_id = i;
692 : 0 : goto l_end;
693 : : }
694 [ # # ]: 0 : if (tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6) {
695 [ # # ]: 0 : if (!memcmp(&tunnel.ipv6, &per->ip_addr.dst_ipv6,
696 : : sizeof(tunnel.ipv6))) {
697 : 0 : tcam_id = i;
698 : 0 : goto l_end;
699 : : }
700 : : }
701 : : }
702 : : }
703 : :
704 : 0 : l_end:
705 : 0 : return tcam_id;
706 : : }
707 : :
708 : : static uint16_t
709 : 0 : sxe2_ipsec_group_id_find(struct sxe2_ipsec_rx_udp_group *rx_udp_group,
710 : : uint16_t udp_port, uint8_t sport_en, uint8_t dport_en, uint16_t len)
711 : : {
712 : 0 : struct sxe2_ipsec_rx_udp_group *per = NULL;
713 : 0 : uint16_t group_id = 0XFFFF;
714 : 0 : uint16_t i;
715 : :
716 [ # # ]: 0 : for (i = 0; i < len; i++) {
717 : 0 : per = &rx_udp_group[i];
718 [ # # # # ]: 0 : if (per->udp_port == udp_port && per->sport_en == sport_en &&
719 [ # # ]: 0 : per->dport_en == dport_en) {
720 : 0 : group_id = i;
721 : 0 : goto l_end;
722 : : }
723 : : }
724 : :
725 : 0 : l_end:
726 : 0 : return group_id;
727 : : }
728 : :
729 : : static void
730 : 0 : sxe2_ipsec_rx_sa_fill(struct sxe2_ipsec_rx_sa *rx_sa,
731 : : struct rte_security_session_conf *conf)
732 : : {
733 : 0 : uint8_t *dst = NULL;
734 : 0 : uint8_t len = 0;
735 : :
736 [ # # ]: 0 : memcpy(&rx_sa->xform, &conf->ipsec, sizeof(struct rte_security_ipsec_xform));
737 : :
738 [ # # ]: 0 : if (conf->crypto_xform->next)
739 : 0 : rx_sa->mode = SXE2_IPSEC_MODE_ENC_AND_AUTH;
740 : : else
741 : 0 : rx_sa->mode = SXE2_IPSEC_MODE_ONLY_ENCRYPT;
742 : :
743 [ # # ]: 0 : if (conf->crypto_xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
744 [ # # ]: 0 : if (conf->crypto_xform->cipher.algo == SXE2_RTE_RTE_CRYPTO_CIPHER_SM4_CBC)
745 : 0 : rx_sa->algo = SXE2_IPSEC_ALGO_SM4_CBC_AND_SM3_96_HMAC;
746 : : else
747 : 0 : rx_sa->algo = SXE2_IPSEC_ALGO_AES_CBC_AND_SHA256_128_HMAC;
748 : : } else {
749 [ # # ]: 0 : if (conf->crypto_xform->auth.algo == SXE2_RTE_CRYPTO_AUTH_SM3_HMAC)
750 : 0 : rx_sa->algo = SXE2_IPSEC_ALGO_SM4_CBC_AND_SM3_96_HMAC;
751 : : else
752 : 0 : rx_sa->algo = SXE2_IPSEC_ALGO_AES_CBC_AND_SHA256_128_HMAC;
753 : : }
754 : :
755 [ # # ]: 0 : if (conf->crypto_xform->next) {
756 : 0 : dst = rx_sa->auth_key;
757 : 0 : len = conf->crypto_xform->auth.key.length;
758 : 0 : memcpy(dst, conf->crypto_xform->auth.key.data, len);
759 : :
760 : 0 : dst = rx_sa->enc_key;
761 : 0 : len = conf->crypto_xform->next->cipher.key.length;
762 : 0 : memcpy(dst, conf->crypto_xform->next->cipher.key.data, len);
763 : : } else {
764 : 0 : dst = rx_sa->enc_key;
765 : 0 : len = conf->crypto_xform->cipher.key.length;
766 : 0 : memcpy(dst, conf->crypto_xform->cipher.key.data, len);
767 : : }
768 : :
769 : 0 : rx_sa->spi = conf->ipsec.spi;
770 : 0 : }
771 : :
772 : : static int32_t
773 : 0 : sxe2_ipsec_rx_tcam_fill(struct sxe2_security_ctx *sxe2_sctx, uint16_t *tcam_id,
774 : : struct rte_security_session_conf *conf)
775 : : {
776 : 0 : int32_t ret = -1;
777 : 0 : uint16_t len = sxe2_sctx->ipsec_ctx.max_tcam;
778 : 0 : struct sxe2_ipsec_rx_tcam *rx_tcam = NULL;
779 : :
780 : 0 : *tcam_id = sxe2_ipsec_tcam_id_find(sxe2_sctx->ipsec_ctx.rx_tcam,
781 : : conf->ipsec.tunnel, len);
782 [ # # ]: 0 : if (*tcam_id == 0XFFFF) {
783 : 0 : *tcam_id = sxe2_ipsec_id_alloc(sxe2_sctx->ipsec_ctx.bmp.rx_tcam_bmp, len);
784 [ # # ]: 0 : if (*tcam_id == 0xFFFF) {
785 : 0 : ret = -ENOMEM;
786 : 0 : goto l_end;
787 : : }
788 : 0 : rx_tcam = &sxe2_sctx->ipsec_ctx.rx_tcam[*tcam_id];
789 : :
790 : 0 : rx_tcam->ip_addr.type = conf->ipsec.tunnel.type;
791 [ # # ]: 0 : if (rx_tcam->ip_addr.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
792 : 0 : rx_tcam->ip_addr.dst_ipv4 = (uint32_t)conf->ipsec.tunnel.ipv4.dst_ip.s_addr;
793 : : } else {
794 : 0 : memcpy(&rx_tcam->ip_addr.dst_ipv6, &conf->ipsec.tunnel.ipv6.dst_addr,
795 : : sizeof(rx_tcam->ip_addr.dst_ipv6));
796 : : }
797 : : } else {
798 : 0 : rx_tcam = &sxe2_sctx->ipsec_ctx.rx_tcam[*tcam_id];
799 : : }
800 : 0 : rx_tcam->ref_cnt++;
801 : 0 : ret = 0;
802 : :
803 : 0 : l_end:
804 : 0 : return ret;
805 : : }
806 : :
807 : : static int32_t
808 : 0 : sxe2_ipsec_rx_udp_group_fill(struct sxe2_security_ctx *sxe2_sctx, uint16_t *udp_group_id,
809 : : struct rte_security_session_conf *conf)
810 : : {
811 : 0 : int32_t ret = -1;
812 : 0 : uint16_t len = sxe2_sctx->ipsec_ctx.max_udp_group;
813 : 0 : struct sxe2_ipsec_rx_udp_group *rx_udp_group = NULL;
814 : 0 : uint8_t sport_en = 0;
815 : 0 : uint8_t dport_en = 0;
816 : 0 : uint16_t udp_port = 0;
817 : :
818 [ # # ]: 0 : if (!conf->ipsec.options.udp_encap) {
819 : 0 : ret = 0;
820 : 0 : goto l_end;
821 : : }
822 : :
823 [ # # ]: 0 : if (conf->ipsec.udp.sport) {
824 : 0 : sport_en = 1;
825 : 0 : udp_port = conf->ipsec.udp.sport;
826 : : } else {
827 : : sport_en = 0;
828 : : }
829 [ # # ]: 0 : if (conf->ipsec.udp.dport) {
830 : 0 : dport_en = 1;
831 : 0 : udp_port = conf->ipsec.udp.dport;
832 : : } else {
833 : : dport_en = 0;
834 : : }
835 : :
836 : 0 : *udp_group_id = sxe2_ipsec_group_id_find(sxe2_sctx->ipsec_ctx.rx_udp_group,
837 : : udp_port, sport_en, dport_en, len);
838 [ # # ]: 0 : if (*udp_group_id == 0XFFFF) {
839 : 0 : *udp_group_id = sxe2_ipsec_id_alloc(sxe2_sctx->ipsec_ctx.bmp.rx_udp_bmp, len);
840 [ # # ]: 0 : if (*udp_group_id == 0xFFFF) {
841 : 0 : ret = -ENOMEM;
842 : 0 : goto l_end;
843 : : }
844 : 0 : rx_udp_group = &sxe2_sctx->ipsec_ctx.rx_udp_group[*udp_group_id];
845 : 0 : rx_udp_group->sport_en = sport_en;
846 : 0 : rx_udp_group->dport_en = dport_en;
847 : 0 : rx_udp_group->udp_port = udp_port;
848 : : } else {
849 : 0 : rx_udp_group = &sxe2_sctx->ipsec_ctx.rx_udp_group[*udp_group_id];
850 : : }
851 : 0 : rx_udp_group->ref_cnt++;
852 : 0 : ret = 0;
853 : :
854 : 0 : l_end:
855 : 0 : return ret;
856 : : }
857 : :
858 : : static int32_t
859 : 0 : sxe2_ipsec_rx_sa_add(struct sxe2_security_ctx *sxe2_sctx,
860 : : struct rte_security_session_conf *conf,
861 : : struct sxe2_security_session *sxe2_sess)
862 : : {
863 : 0 : struct sxe2_ipsec_rx_tcam *rx_tcam = NULL;
864 : 0 : struct sxe2_ipsec_rx_sa *rx_sa = NULL;
865 : 0 : struct sxe2_ipsec_rx_udp_group *rx_udp_group = NULL;
866 : 0 : struct rte_bitmap *rx_sa_bmp = sxe2_sctx->ipsec_ctx.bmp.rx_sa_bmp;
867 : 0 : struct rte_bitmap *rx_tcam_bmp = sxe2_sctx->ipsec_ctx.bmp.rx_tcam_bmp;
868 : 0 : uint16_t sa_bits = sxe2_sctx->ipsec_ctx.max_rx_sa;
869 : 0 : uint16_t sa_id = 0xFFFF;
870 : 0 : uint16_t tcam_id = 0xFFFF;
871 : 0 : uint16_t udp_group_id = 0xFFFF;
872 : 0 : int32_t ret = -1;
873 : :
874 : 0 : rte_spinlock_lock(&sxe2_sctx->security_lock);
875 : 0 : sa_id = sxe2_ipsec_id_alloc(rx_sa_bmp, sa_bits);
876 [ # # ]: 0 : if (sa_id == 0xFFFF) {
877 : 0 : PMD_LOG_ERR(DRV, "Failed to allocate ipsec rx sa index.");
878 : 0 : ret = -ENOMEM;
879 : 0 : goto l_end;
880 : : }
881 : 0 : rx_sa = &sxe2_sctx->ipsec_ctx.rx_sa[sa_id];
882 : 0 : sxe2_ipsec_rx_sa_fill(rx_sa, conf);
883 : :
884 : 0 : ret = sxe2_ipsec_rx_tcam_fill(sxe2_sctx, &tcam_id, conf);
885 [ # # ]: 0 : if (ret) {
886 : 0 : PMD_LOG_ERR(DRV, "Failed to allocate ipsec rx tcam index.");
887 : 0 : sxe2_ipsec_id_free(rx_sa_bmp, sa_id);
888 : 0 : goto l_end;
889 : : }
890 : 0 : rx_sa->tcam_id = tcam_id;
891 : 0 : rx_tcam = &sxe2_sctx->ipsec_ctx.rx_tcam[tcam_id];
892 : :
893 : 0 : ret = sxe2_ipsec_rx_udp_group_fill(sxe2_sctx, &udp_group_id, conf);
894 [ # # ]: 0 : if (ret) {
895 : 0 : PMD_LOG_ERR(DRV, "Failed to allocate ipsec rx udp group index.");
896 : 0 : sxe2_ipsec_id_free(rx_sa_bmp, sa_id);
897 : 0 : sxe2_ipsec_id_free(rx_tcam_bmp, tcam_id);
898 : 0 : goto l_end;
899 : : }
900 : :
901 [ # # ]: 0 : if (udp_group_id != 0XFFFF) {
902 : 0 : rx_sa->udp_group_id = (uint8_t)udp_group_id;
903 : 0 : rx_udp_group = &sxe2_sctx->ipsec_ctx.rx_udp_group[udp_group_id];
904 : : } else {
905 : 0 : rx_sa->udp_group_id = 0XFF;
906 : : }
907 : :
908 : 0 : ret = sxe2_drv_ipsec_rxsa_add(sxe2_sctx->adapter, rx_sa, rx_tcam, rx_udp_group);
909 [ # # ]: 0 : if (ret) {
910 : 0 : PMD_LOG_ERR(DRV, "Failed to add rx sa.");
911 : 0 : sxe2_ipsec_id_free(rx_sa_bmp, sa_id);
912 : 0 : rx_tcam->ref_cnt--;
913 [ # # ]: 0 : if (rx_tcam->ref_cnt == 0)
914 : 0 : sxe2_ipsec_id_free(rx_tcam_bmp, tcam_id);
915 : :
916 [ # # ]: 0 : if (rx_udp_group != NULL) {
917 : 0 : rx_udp_group->ref_cnt--;
918 [ # # ]: 0 : if (rx_udp_group->ref_cnt == 0)
919 : 0 : sxe2_ipsec_id_free(sxe2_sctx->ipsec_ctx.bmp.rx_udp_bmp,
920 : : udp_group_id);
921 : : }
922 : :
923 : 0 : ret = -EIO;
924 : 0 : goto l_end;
925 : : }
926 : :
927 : 0 : sxe2_ipsec_session_save(sxe2_sctx, conf, sxe2_sess, rx_sa->hw_sa_id, rx_sa->id);
928 : :
929 : 0 : PMD_LOG_INFO(DRV, "Add rx sa success, rx sa id: %u, rx ip id: %u, group id: %u, index: %u.",
930 : : rx_sa->hw_sa_id, rx_sa->hw_ip_id, rx_sa->udp_group_id, rx_sa->id);
931 : :
932 : 0 : l_end:
933 : 0 : rte_spinlock_unlock(&sxe2_sctx->security_lock);
934 : 0 : return ret;
935 : : }
936 : :
937 : : static int32_t
938 : 0 : sxe2_ipsec_hw_table_add(struct sxe2_security_ctx *sxe2_sctx,
939 : : struct rte_security_session_conf *conf,
940 : : struct sxe2_security_session *sxe2_sess)
941 : : {
942 : 0 : int32_t ret = -1;
943 : :
944 [ # # # ]: 0 : switch (conf->ipsec.direction) {
945 : 0 : case RTE_SECURITY_IPSEC_SA_DIR_EGRESS:
946 : 0 : ret = sxe2_ipsec_tx_sa_add(sxe2_sctx, conf, sxe2_sess);
947 : 0 : break;
948 : 0 : case RTE_SECURITY_IPSEC_SA_DIR_INGRESS:
949 : 0 : ret = sxe2_ipsec_rx_sa_add(sxe2_sctx, conf, sxe2_sess);
950 : 0 : break;
951 : 0 : default:
952 : 0 : PMD_LOG_ERR(DRV, "Invalid sa direction.");
953 : 0 : ret = -EINVAL;
954 : 0 : break;
955 : : }
956 : :
957 : 0 : return ret;
958 : : }
959 : :
960 : 0 : int sxe2_ipsec_session_create(void *device,
961 : : struct rte_security_session_conf *conf,
962 : : struct sxe2_security_session *sxe2_sess)
963 : : {
964 : 0 : struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)device;
965 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(eth_dev);
966 : 0 : struct sxe2_security_ctx *sxe2_sctx = &adapter->security_ctx;
967 : 0 : int32_t ret = -1;
968 : :
969 : 0 : ret = sxe2_ipsec_session_conf_valid(sxe2_sctx, conf);
970 [ # # ]: 0 : if (ret) {
971 : 0 : PMD_LOG_ERR(DRV, "Input ipsec session conf invalid.");
972 : 0 : goto l_end;
973 : : }
974 : :
975 : 0 : ret = sxe2_ipsec_hw_table_add(sxe2_sctx, conf, sxe2_sess);
976 [ # # ]: 0 : if (ret)
977 : 0 : goto l_end;
978 : :
979 : 0 : l_end:
980 : 0 : return ret;
981 : : }
982 : :
983 : : static int32_t
984 : 0 : sxe2_ipsec_tx_sa_delete(struct sxe2_security_ctx *sxe2_sctx,
985 : : struct sxe2_security_session *sxe2_sess)
986 : : {
987 : 0 : struct sxe2_ipsec_tx_sa *tx_sa = NULL;
988 : 0 : uint16_t sa_id = sxe2_sess->sa.hw_idx;
989 : 0 : uint16_t sw_sa_id = sxe2_sess->sa.sw_idx;
990 : 0 : int32_t ret = -1;
991 : :
992 [ # # ]: 0 : if (sw_sa_id >= sxe2_sctx->ipsec_ctx.max_tx_sa) {
993 : 0 : ret = 0;
994 : 0 : PMD_LOG_WARN(DRV, "invalid sw sa id: %u.", sw_sa_id);
995 : 0 : goto l_end;
996 : : }
997 : :
998 [ # # ]: 0 : if (!rte_bitmap_get(sxe2_sctx->ipsec_ctx.bmp.tx_sa_bmp, sw_sa_id)) {
999 : 0 : ret = 0;
1000 : 0 : PMD_LOG_WARN(DRV, "bitmap not set, index: %u.", sw_sa_id);
1001 : 0 : goto l_end;
1002 : : }
1003 : :
1004 : 0 : tx_sa = &sxe2_sctx->ipsec_ctx.tx_sa[sw_sa_id];
1005 : :
1006 [ # # ]: 0 : if (tx_sa->hw_sa_id != sa_id) {
1007 : 0 : ret = 0;
1008 : 0 : PMD_LOG_WARN(DRV, "invalid hw sa id: %u != %u.", sa_id, tx_sa->hw_sa_id);
1009 : 0 : goto l_end;
1010 : : }
1011 : :
1012 : 0 : ret = sxe2_drv_ipsec_txsa_delete(sxe2_sctx->adapter, sa_id);
1013 [ # # ]: 0 : if (ret)
1014 : 0 : goto l_end;
1015 : :
1016 : 0 : rte_spinlock_lock(&sxe2_sctx->security_lock);
1017 : 0 : sxe2_ipsec_id_free(sxe2_sctx->ipsec_ctx.bmp.tx_sa_bmp, sw_sa_id);
1018 : 0 : rte_spinlock_unlock(&sxe2_sctx->security_lock);
1019 : :
1020 : 0 : l_end:
1021 : 0 : return ret;
1022 : : }
1023 : :
1024 : : static int32_t
1025 : 0 : sxe2_ipsec_rx_sa_delete(struct sxe2_security_ctx *sxe2_sctx,
1026 : : struct sxe2_security_session *sxe2_sess)
1027 : : {
1028 : 0 : struct sxe2_ipsec_rx_udp_group *rx_udp = NULL;
1029 : 0 : struct sxe2_ipsec_rx_tcam *rx_tcam = NULL;
1030 : 0 : struct sxe2_ipsec_rx_sa *rx_sa = NULL;
1031 : 0 : uint16_t sa_id = sxe2_sess->sa.hw_idx;
1032 : 0 : uint16_t sw_sa_id = sxe2_sess->sa.sw_idx;
1033 : 0 : int32_t ret = -1;
1034 : :
1035 [ # # ]: 0 : if (sw_sa_id >= sxe2_sctx->ipsec_ctx.max_rx_sa) {
1036 : 0 : ret = 0;
1037 : 0 : PMD_LOG_WARN(DRV, "invalid sw sa id: %u.", sw_sa_id);
1038 : 0 : goto l_end;
1039 : : }
1040 : :
1041 [ # # ]: 0 : if (!rte_bitmap_get(sxe2_sctx->ipsec_ctx.bmp.rx_sa_bmp, sw_sa_id)) {
1042 : 0 : ret = 0;
1043 : 0 : PMD_LOG_INFO(DRV, "bitmap not set, id: %u.", sw_sa_id);
1044 : 0 : goto l_end;
1045 : : }
1046 : :
1047 : 0 : rx_sa = &sxe2_sctx->ipsec_ctx.rx_sa[sw_sa_id];
1048 : :
1049 [ # # ]: 0 : if (rx_sa->hw_sa_id != sa_id) {
1050 : 0 : ret = 0;
1051 : 0 : PMD_LOG_WARN(DRV, "invalid hw sa id: %u != %u.", sa_id, rx_sa->hw_sa_id);
1052 : 0 : goto l_end;
1053 : : }
1054 : :
1055 : 0 : ret = sxe2_drv_ipsec_rxsa_delete(sxe2_sctx->adapter, rx_sa);
1056 [ # # ]: 0 : if (ret)
1057 : 0 : goto l_end;
1058 : :
1059 : 0 : rte_spinlock_lock(&sxe2_sctx->security_lock);
1060 : 0 : sxe2_ipsec_id_free(sxe2_sctx->ipsec_ctx.bmp.rx_sa_bmp, sw_sa_id);
1061 : :
1062 : 0 : rx_tcam = &sxe2_sctx->ipsec_ctx.rx_tcam[rx_sa->tcam_id];
1063 : 0 : rx_tcam->ref_cnt--;
1064 [ # # ]: 0 : if (rx_tcam->ref_cnt == 0)
1065 : 0 : sxe2_ipsec_id_free(sxe2_sctx->ipsec_ctx.bmp.rx_tcam_bmp, rx_sa->tcam_id);
1066 : :
1067 [ # # ]: 0 : if (rx_sa->udp_group_id == 0xFF) {
1068 : 0 : PMD_LOG_INFO(DRV, "Not need to release udp group resource.");
1069 : 0 : rte_spinlock_unlock(&sxe2_sctx->security_lock);
1070 : 0 : goto l_end;
1071 : : }
1072 : 0 : rx_udp = &sxe2_sctx->ipsec_ctx.rx_udp_group[rx_sa->udp_group_id];
1073 : 0 : rx_udp->ref_cnt--;
1074 [ # # ]: 0 : if (rx_udp->ref_cnt == 0)
1075 : 0 : sxe2_ipsec_id_free(sxe2_sctx->ipsec_ctx.bmp.rx_udp_bmp, rx_sa->udp_group_id);
1076 : 0 : rte_spinlock_unlock(&sxe2_sctx->security_lock);
1077 : :
1078 : 0 : l_end:
1079 : 0 : return ret;
1080 : : }
1081 : :
1082 : : static int32_t
1083 : 0 : sxe2_ipsec_hw_table_delete(struct sxe2_security_ctx *sxe2_sctx,
1084 : : struct sxe2_security_session *sxe2_sess)
1085 : : {
1086 : 0 : int32_t ret = -1;
1087 : :
1088 [ # # # ]: 0 : switch (sxe2_sess->direction) {
1089 : 0 : case RTE_SECURITY_IPSEC_SA_DIR_EGRESS:
1090 : 0 : ret = sxe2_ipsec_tx_sa_delete(sxe2_sctx, sxe2_sess);
1091 : 0 : break;
1092 : 0 : case RTE_SECURITY_IPSEC_SA_DIR_INGRESS:
1093 : 0 : ret = sxe2_ipsec_rx_sa_delete(sxe2_sctx, sxe2_sess);
1094 : 0 : break;
1095 : 0 : default:
1096 : 0 : PMD_LOG_ERR(DRV, "Invalid sa direction.");
1097 : 0 : ret = -EINVAL;
1098 : 0 : break;
1099 : : }
1100 : :
1101 : 0 : return ret;
1102 : : }
1103 : :
1104 : 0 : int sxe2_ipsec_session_destroy(void *device, struct rte_security_session *session)
1105 : : {
1106 : 0 : struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)device;
1107 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(eth_dev);
1108 : 0 : struct sxe2_security_ctx *sxe2_sctx = &adapter->security_ctx;
1109 : 0 : struct sxe2_security_session *sxe2_sess = NULL;
1110 : 0 : sxe2_sess = SECURITY_GET_SESS_PRIV(session);
1111 : 0 : int32_t ret = -1;
1112 : :
1113 [ # # ]: 0 : if (unlikely(sxe2_sess == NULL || sxe2_sess->adapter != adapter)) {
1114 : 0 : PMD_LOG_ERR(DRV, "Invalid device adapter.");
1115 : 0 : ret = -EINVAL;
1116 : 0 : goto l_end;
1117 : : }
1118 : :
1119 : 0 : ret = sxe2_ipsec_hw_table_delete(sxe2_sctx, sxe2_sess);
1120 [ # # ]: 0 : if (ret) {
1121 : 0 : ret = -EIO;
1122 : 0 : PMD_LOG_ERR(DRV, "Failed to delete ipsec hw tables.");
1123 : 0 : goto l_end;
1124 : : }
1125 : :
1126 : 0 : memset(sxe2_sess, 0, sizeof(struct sxe2_security_session));
1127 : :
1128 : 0 : PMD_LOG_INFO(DRV, "Delete ipsec session success, sa_id: %u, spi: %u.",
1129 : : sxe2_sess->sa.hw_idx, sxe2_sess->sa.spi);
1130 : :
1131 : 0 : l_end:
1132 : 0 : return ret;
1133 : : }
1134 : :
1135 : 0 : int sxe2_ipsec_pkt_metadata_set(void *device, struct rte_security_session *session,
1136 : : struct rte_mbuf *m, void *params)
1137 : : {
1138 : 0 : struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)device;
1139 : 0 : struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(eth_dev);
1140 : 0 : struct sxe2_security_ctx *sxe2_sctx = &adapter->security_ctx;
1141 : 0 : struct sxe2_security_session *sxe2_sess = NULL;
1142 : 0 : struct sxe2_ipsec_pkt_metadata *md = NULL;
1143 : 0 : uint16_t offset = 0;
1144 : 0 : int32_t ret = -1;
1145 : :
1146 : 0 : sxe2_sess = SECURITY_GET_SESS_PRIV(session);
1147 [ # # ]: 0 : if (unlikely(sxe2_sess == NULL || sxe2_sess->adapter != adapter)) {
1148 : 0 : PMD_LOG_ERR(DRV, "Invalid parameters.");
1149 : 0 : ret = -EINVAL;
1150 : 0 : goto l_end;
1151 : : }
1152 : :
1153 : 0 : offset = ((struct sxe2_ipsec_metadata_params *)params)->esp_header_offset;
1154 [ # # ]: 0 : if (offset <= IPSEC_ESP_OFFSET_MIN || offset >= IPSEC_ESP_OFFSET_MAX) {
1155 : 0 : PMD_LOG_ERR(DRV, "Invalid esp header offset.");
1156 : 0 : ret = -EINVAL;
1157 : 0 : goto l_end;
1158 : : }
1159 : :
1160 : 0 : md = RTE_MBUF_DYNFIELD(m, sxe2_sctx->ipsec_ctx.md_offset, struct sxe2_ipsec_pkt_metadata *);
1161 : :
1162 : 0 : memcpy(md, &sxe2_sess->pkt_metadata_template, sizeof(struct sxe2_ipsec_pkt_metadata));
1163 : 0 : md->esp_head_offset = offset;
1164 : :
1165 : 0 : PMD_LOG_INFO(DRV, "ipsec metadata set, offset:%u, said:%u, mode:%u, algo:%u.", offset,
1166 : : sxe2_sess->pkt_metadata_template.sa_idx, sxe2_sess->pkt_metadata_template.mode,
1167 : : sxe2_sess->pkt_metadata_template.algo);
1168 : :
1169 : 0 : ret = 0;
1170 : :
1171 : 0 : l_end:
1172 : 0 : return ret;
1173 : : }
1174 : :
1175 : 0 : int sxe2_ipsec_pkt_md_offset_get(struct sxe2_adapter *adapter)
1176 : : {
1177 : 0 : return adapter->security_ctx.ipsec_ctx.md_offset;
1178 : : }
1179 : :
1180 : 0 : static void sxe2_ipsec_enc_aes_cbc_fill(struct rte_cryptodev_capabilities *cap)
1181 : : {
1182 : 0 : cap->sym.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1183 : :
1184 : 0 : cap->sym.cipher.algo = SXE2_RTE_CRYPTO_CIPHER_AES_CBC;
1185 : :
1186 : 0 : cap->sym.cipher.block_size = SXE2_SECURITY_BLOCK_SIZE_16;
1187 : :
1188 : 0 : cap->sym.cipher.key_size.min = SXE2_IPSEC_AES_KEY_MIN;
1189 : 0 : cap->sym.cipher.key_size.max = SXE2_IPSEC_AES_KEY_MAX;
1190 : 0 : cap->sym.cipher.key_size.increment = SXE2_IPSEC_AES_KEY_INC;
1191 : :
1192 : 0 : cap->sym.cipher.iv_size.min = SXE2_IPSEC_AES_IV_MIN;
1193 : 0 : cap->sym.cipher.iv_size.max = SXE2_IPSEC_AES_IV_MAX;
1194 : 0 : cap->sym.cipher.iv_size.increment = SXE2_IPSEC_AES_IV_INC;
1195 : :
1196 : 0 : cap->sym.cipher.dataunit_set |= RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_512_BYTES;
1197 : 0 : }
1198 : :
1199 : 0 : static void sxe2_ipsec_enc_sm4_cbc_fill(struct rte_cryptodev_capabilities *cap)
1200 : : {
1201 : 0 : cap->sym.xform_type = RTE_CRYPTO_SYM_XFORM_CIPHER;
1202 : :
1203 : 0 : cap->sym.cipher.algo = SXE2_RTE_RTE_CRYPTO_CIPHER_SM4_CBC;
1204 : :
1205 : 0 : cap->sym.cipher.block_size = SXE2_SECURITY_BLOCK_SIZE_16;
1206 : :
1207 : 0 : cap->sym.cipher.key_size.min = SXE2_IPSEC_SM4_KEY_MIN;
1208 : 0 : cap->sym.cipher.key_size.max = SXE2_IPSEC_SM4_KEY_MAX;
1209 : 0 : cap->sym.cipher.key_size.increment = SXE2_IPSEC_SM4_KEY_INC;
1210 : :
1211 : 0 : cap->sym.cipher.iv_size.min = SXE2_IPSEC_SM4_IV_MIN;
1212 : 0 : cap->sym.cipher.iv_size.max = SXE2_IPSEC_SM4_IV_MAX;
1213 : 0 : cap->sym.cipher.iv_size.increment = SXE2_IPSEC_SM4_IV_INC;
1214 : :
1215 : 0 : cap->sym.cipher.dataunit_set |= RTE_CRYPTO_CIPHER_DATA_UNIT_LEN_512_BYTES;
1216 : 0 : }
1217 : :
1218 : 0 : static void sxe2_ipsec_auth_sha_hmac_fill(struct rte_cryptodev_capabilities *cap)
1219 : : {
1220 : 0 : cap->sym.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH;
1221 : :
1222 : 0 : cap->sym.auth.algo = SXE2_RTE_CRYPTO_AUTH_SHA256_HMAC;
1223 : :
1224 : 0 : cap->sym.auth.block_size = SXE2_SECURITY_BLOCK_SIZE_64;
1225 : :
1226 : 0 : cap->sym.auth.key_size.min = SXE2_IPSEC_SHA_KEY_MIN;
1227 : 0 : cap->sym.auth.key_size.max = SXE2_IPSEC_SHA_KEY_MAX;
1228 : 0 : cap->sym.auth.key_size.increment = SXE2_IPSEC_SHA_KEY_INC;
1229 : :
1230 : 0 : cap->sym.auth.iv_size.min = SXE2_IPSEC_SHA_IV_MIN;
1231 : 0 : cap->sym.auth.iv_size.max = SXE2_IPSEC_SHA_IV_MAX;
1232 : 0 : cap->sym.auth.iv_size.increment = SXE2_IPSEC_SHA_IV_INC;
1233 : :
1234 : 0 : cap->sym.auth.digest_size.min = SXE2_IPSEC_SHA_DIGEST_MIN;
1235 : 0 : cap->sym.auth.digest_size.max = SXE2_IPSEC_SHA_DIGEST_MAX;
1236 : 0 : cap->sym.auth.digest_size.increment = SXE2_IPSEC_SHA_DIGEST_INC;
1237 : :
1238 : 0 : cap->sym.auth.aad_size.min = SXE2_IPSEC_AAD_MIN;
1239 : 0 : cap->sym.auth.aad_size.max = SXE2_IPSEC_AAD_MAX;
1240 : 0 : cap->sym.auth.aad_size.increment = SXE2_IPSEC_AAD_INC;
1241 : 0 : }
1242 : :
1243 : 0 : static void sxe2_ipsec_auth_sm3_hmac_fill(struct rte_cryptodev_capabilities *cap)
1244 : : {
1245 : 0 : cap->sym.xform_type = RTE_CRYPTO_SYM_XFORM_AUTH;
1246 : :
1247 : 0 : cap->sym.auth.algo = SXE2_RTE_CRYPTO_AUTH_SM3_HMAC;
1248 : :
1249 : 0 : cap->sym.auth.block_size = SXE2_SECURITY_BLOCK_SIZE_64;
1250 : :
1251 : 0 : cap->sym.auth.key_size.min = SXE2_IPSEC_SM3_KEY_MIN;
1252 : 0 : cap->sym.auth.key_size.max = SXE2_IPSEC_SM3_KEY_MAX;
1253 : 0 : cap->sym.auth.key_size.increment = SXE2_IPSEC_SM3_KEY_INC;
1254 : :
1255 : 0 : cap->sym.auth.iv_size.min = SXE2_IPSEC_SM3_IV_MIN;
1256 : 0 : cap->sym.auth.iv_size.max = SXE2_IPSEC_SM3_IV_MAX;
1257 : 0 : cap->sym.auth.iv_size.increment = SXE2_IPSEC_SM3_IV_INC;
1258 : :
1259 : 0 : cap->sym.auth.digest_size.min = SXE2_IPSEC_SM3_DIGEST_MIN;
1260 : 0 : cap->sym.auth.digest_size.max = SXE2_IPSEC_SM3_DIGEST_MAX;
1261 : 0 : cap->sym.auth.digest_size.increment = SXE2_IPSEC_SM3_DIGEST_INC;
1262 : :
1263 : 0 : cap->sym.auth.aad_size.min = SXE2_IPSEC_AAD_MIN;
1264 : 0 : cap->sym.auth.aad_size.max = SXE2_IPSEC_AAD_MAX;
1265 : 0 : cap->sym.auth.aad_size.increment = SXE2_IPSEC_AAD_INC;
1266 : 0 : }
1267 : :
1268 : : static int32_t
1269 : 0 : sxe2_ipsec_capabilities_init(struct sxe2_security_ctx *sxe2_sctx)
1270 : : {
1271 : 0 : struct rte_cryptodev_capabilities *capabilities = NULL;
1272 : 0 : struct sxe2_security_capabilities *sxe2_cap =
1273 : : &sxe2_sctx->sxe2_capabilities[SXE2_SECURITY_PROTOCOL_IPSEC];
1274 : 0 : int32_t ret = -1;
1275 : 0 : uint8_t index = 0;
1276 : :
1277 : 0 : sxe2_cap->action = RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO;
1278 : 0 : sxe2_cap->ipsec.proto = RTE_SECURITY_IPSEC_SA_PROTO_ESP;
1279 : 0 : sxe2_cap->ipsec.mode = RTE_SECURITY_IPSEC_SA_MODE_TUNNEL;
1280 : 0 : sxe2_cap->ipsec.options.stats = 1;
1281 : :
1282 : 0 : capabilities = rte_zmalloc("security_caps",
1283 : : sizeof(struct rte_cryptodev_capabilities) * SXE2_IPSEC_CAP_MAX, 0);
1284 [ # # ]: 0 : if (capabilities == NULL) {
1285 : 0 : ret = -ENOMEM;
1286 : 0 : goto l_end;
1287 : : }
1288 : :
1289 [ # # ]: 0 : for (index = 0; index < SXE2_IPSEC_CAP_MAX; index++) {
1290 : 0 : capabilities[index].op = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
1291 [ # # # # ]: 0 : switch (index) {
1292 : 0 : case SXE2_IPSEC_CAP_ENC_AES_CBC:
1293 : 0 : sxe2_ipsec_enc_aes_cbc_fill(&capabilities[index]);
1294 : : break;
1295 : 0 : case SXE2_IPSEC_CAP_ENC_SM4_CBC:
1296 : 0 : sxe2_ipsec_enc_sm4_cbc_fill(&capabilities[index]);
1297 : : break;
1298 : 0 : case SXE2_IPSEC_CAP_AUTH_SHA256_HMAC:
1299 : 0 : sxe2_ipsec_auth_sha_hmac_fill(&capabilities[index]);
1300 : : break;
1301 : 0 : case SXE2_IPSEC_CAP_AUTH_SM3_HMAC:
1302 : 0 : sxe2_ipsec_auth_sm3_hmac_fill(&capabilities[index]);
1303 : : break;
1304 : : default:
1305 : : break;
1306 : : }
1307 : : }
1308 : :
1309 : 0 : sxe2_cap->crypto_capabilities = capabilities;
1310 : 0 : ret = 0;
1311 : :
1312 : 0 : l_end:
1313 : 0 : return ret;
1314 : : }
1315 : :
1316 : : static void
1317 : 0 : sxe2_ipsec_tx_sa_init(struct sxe2_ipsec_tx_sa *tx_sa, uint16_t len)
1318 : : {
1319 : 0 : struct sxe2_ipsec_tx_sa *per = NULL;
1320 : 0 : uint16_t i;
1321 : :
1322 : 0 : memset(tx_sa, 0, sizeof(struct sxe2_ipsec_tx_sa) * len);
1323 [ # # ]: 0 : for (i = 0; i < len; i++) {
1324 : 0 : per = &tx_sa[i];
1325 : 0 : per->id = i;
1326 : : }
1327 : 0 : }
1328 : :
1329 : : static void
1330 : 0 : sxe2_ipsec_rx_sa_init(struct sxe2_ipsec_rx_sa *rx_sa, uint16_t len)
1331 : : {
1332 : 0 : struct sxe2_ipsec_rx_sa *per = NULL;
1333 : 0 : uint16_t i;
1334 : :
1335 : 0 : memset(rx_sa, 0, sizeof(struct sxe2_ipsec_rx_sa) * len);
1336 [ # # ]: 0 : for (i = 0; i < len; i++) {
1337 : 0 : per = &rx_sa[i];
1338 : 0 : per->id = i;
1339 : : }
1340 : 0 : }
1341 : :
1342 : : static void
1343 : 0 : sxe2_ipsec_rx_tcam_init(struct sxe2_ipsec_rx_tcam *rx_tcam, uint16_t len)
1344 : : {
1345 : 0 : struct sxe2_ipsec_rx_tcam *per = NULL;
1346 : 0 : uint16_t i;
1347 : :
1348 : 0 : memset(rx_tcam, 0, sizeof(struct sxe2_ipsec_rx_tcam) * len);
1349 [ # # ]: 0 : for (i = 0; i < len; i++) {
1350 : 0 : per = &rx_tcam[i];
1351 : 0 : per->id = i;
1352 : : }
1353 : 0 : }
1354 : :
1355 : : static void
1356 : 0 : sxe2_ipsec_rx_udp_group_init(struct sxe2_ipsec_rx_udp_group *rx_udp_group, uint16_t len)
1357 : : {
1358 : 0 : struct sxe2_ipsec_rx_udp_group *per = NULL;
1359 : 0 : uint16_t i;
1360 : :
1361 : 0 : memset(rx_udp_group, 0, sizeof(struct sxe2_ipsec_rx_udp_group) * len);
1362 [ # # ]: 0 : for (i = 0; i < len; i++) {
1363 : 0 : per = &rx_udp_group[i];
1364 : 0 : per->id = i;
1365 : : }
1366 : 0 : }
1367 : :
1368 : : static int32_t
1369 : 0 : sxe2_ipsec_hw_table_init(struct sxe2_security_ctx *sxe2_sctx)
1370 : : {
1371 : 0 : struct sxe2_ipsec_tx_sa *tx_sa = NULL;
1372 : 0 : struct sxe2_ipsec_rx_sa *rx_sa = NULL;
1373 : 0 : struct sxe2_ipsec_rx_tcam *rx_tcam = NULL;
1374 : 0 : struct sxe2_ipsec_rx_udp_group *rx_udp_group = NULL;
1375 : 0 : uint16_t max_tx_sa = sxe2_sctx->ipsec_ctx.max_tx_sa;
1376 : 0 : uint16_t max_rx_sa = sxe2_sctx->ipsec_ctx.max_rx_sa;
1377 : 0 : uint16_t max_tcam = sxe2_sctx->ipsec_ctx.max_tcam;
1378 : 0 : uint16_t max_udp_group = sxe2_sctx->ipsec_ctx.max_udp_group;
1379 : 0 : int32_t ret = -1;
1380 : :
1381 : 0 : tx_sa = rte_zmalloc("sxe2_ipsec_tx_sa", sizeof(struct sxe2_ipsec_tx_sa) * max_tx_sa, 0);
1382 [ # # ]: 0 : if (tx_sa == NULL) {
1383 : 0 : ret = -ENOMEM;
1384 : 0 : goto l_end;
1385 : : }
1386 : 0 : sxe2_ipsec_tx_sa_init(tx_sa, max_tx_sa);
1387 : 0 : sxe2_sctx->ipsec_ctx.tx_sa = tx_sa;
1388 : :
1389 : 0 : rx_sa = rte_zmalloc("sxe2_ipsec_rx_sa", sizeof(struct sxe2_ipsec_rx_sa) * max_rx_sa, 0);
1390 [ # # ]: 0 : if (rx_sa == NULL) {
1391 : 0 : ret = -ENOMEM;
1392 : 0 : goto l_end;
1393 : : }
1394 : 0 : sxe2_ipsec_rx_sa_init(rx_sa, max_rx_sa);
1395 : 0 : sxe2_sctx->ipsec_ctx.rx_sa = rx_sa;
1396 : :
1397 : 0 : rx_tcam = rte_zmalloc("sxe2_ipsec_rx_tcam",
1398 : : sizeof(struct sxe2_ipsec_rx_tcam) * max_tcam, 0);
1399 [ # # ]: 0 : if (rx_tcam == NULL) {
1400 : 0 : ret = -ENOMEM;
1401 : 0 : goto l_end;
1402 : : }
1403 : 0 : sxe2_ipsec_rx_tcam_init(rx_tcam, max_tcam);
1404 : 0 : sxe2_sctx->ipsec_ctx.rx_tcam = rx_tcam;
1405 : :
1406 : 0 : rx_udp_group = rte_zmalloc("sxe2_ipsec_rx_udp_group",
1407 : : sizeof(struct sxe2_ipsec_rx_udp_group) * max_udp_group, 0);
1408 [ # # ]: 0 : if (rx_udp_group == NULL) {
1409 : 0 : ret = -ENOMEM;
1410 : 0 : goto l_end;
1411 : : }
1412 : 0 : sxe2_ipsec_rx_udp_group_init(rx_udp_group, max_udp_group);
1413 : 0 : sxe2_sctx->ipsec_ctx.rx_udp_group = rx_udp_group;
1414 : :
1415 : 0 : ret = 0;
1416 : :
1417 : 0 : l_end:
1418 [ # # ]: 0 : if (ret) {
1419 [ # # ]: 0 : if (tx_sa != NULL) {
1420 : 0 : rte_free(tx_sa);
1421 : 0 : sxe2_sctx->ipsec_ctx.tx_sa = NULL;
1422 : : }
1423 [ # # ]: 0 : if (rx_sa != NULL) {
1424 : 0 : rte_free(rx_sa);
1425 : 0 : sxe2_sctx->ipsec_ctx.rx_sa = NULL;
1426 : : }
1427 [ # # ]: 0 : if (rx_tcam != NULL) {
1428 : 0 : rte_free(rx_tcam);
1429 : 0 : sxe2_sctx->ipsec_ctx.rx_tcam = NULL;
1430 : : }
1431 [ # # ]: 0 : if (rx_udp_group != NULL) {
1432 : 0 : rte_free(rx_udp_group);
1433 : 0 : sxe2_sctx->ipsec_ctx.rx_udp_group = NULL;
1434 : : }
1435 : : }
1436 : 0 : return ret;
1437 : : }
1438 : :
1439 : 0 : int32_t sxe2_ipsec_init(struct sxe2_adapter *adapter)
1440 : : {
1441 : 0 : struct sxe2_security_ctx *sxe2_sctx = &adapter->security_ctx;
1442 : 0 : struct sxe2_security_capabilities *sxe2_cap = NULL;
1443 : 0 : int32_t ret = -1;
1444 : 0 : struct rte_mbuf_dynfield pkt_md_dynfield = {
1445 : : .name = "sxe2_ipsec_pkt_metadata",
1446 : : .size = sizeof(struct sxe2_ipsec_pkt_metadata),
1447 : : .align = alignof(struct sxe2_ipsec_pkt_metadata)
1448 : : };
1449 : :
1450 : 0 : PMD_LOG_INFO(INIT, "Init ipsec.");
1451 : :
1452 : 0 : sxe2_sctx->ipsec_ctx.md_offset = rte_mbuf_dynfield_register(&pkt_md_dynfield);
1453 [ # # ]: 0 : if (sxe2_sctx->ipsec_ctx.md_offset < 0) {
1454 : 0 : PMD_LOG_ERR(INIT, "Failed to register ipsec mbuf dynamic field.");
1455 : 0 : ret = -EIO;
1456 : 0 : goto l_end;
1457 : : }
1458 : :
1459 : 0 : ret = sxe2_ipsec_capabilities_init(sxe2_sctx);
1460 [ # # ]: 0 : if (ret) {
1461 : 0 : PMD_LOG_ERR(INIT, "Failed to init ipsec capabilities.");
1462 : 0 : goto l_end;
1463 : : }
1464 : :
1465 : 0 : ret = sxe2_drv_ipsec_get_capa(adapter);
1466 [ # # ]: 0 : if (ret) {
1467 : 0 : PMD_LOG_ERR(INIT, "Failed to get ipsec capabilities.");
1468 : 0 : goto l_caps_free;
1469 : : }
1470 : :
1471 : 0 : ret = sxe2_ipsec_bitmap_init(sxe2_sctx);
1472 [ # # ]: 0 : if (ret) {
1473 : 0 : PMD_LOG_ERR(INIT, "Failed to init ipsec bitmap.");
1474 : 0 : goto l_caps_free;
1475 : : }
1476 : :
1477 : 0 : ret = sxe2_ipsec_hw_table_init(sxe2_sctx);
1478 [ # # ]: 0 : if (ret) {
1479 : 0 : PMD_LOG_ERR(INIT, "Failed to init ipsec hw table.");
1480 : 0 : goto l_bitmap_free;
1481 : : }
1482 : :
1483 : 0 : goto l_end;
1484 : :
1485 : 0 : l_bitmap_free:
1486 : :
1487 [ # # ]: 0 : if (sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem != NULL) {
1488 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem);
1489 : 0 : sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem = NULL;
1490 : : }
1491 [ # # ]: 0 : if (sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem != NULL) {
1492 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem);
1493 : 0 : sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem = NULL;
1494 : : }
1495 [ # # ]: 0 : if (sxe2_sctx->ipsec_ctx.bmp.rx_tcam_mem != NULL) {
1496 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.rx_tcam_mem);
1497 : 0 : sxe2_sctx->ipsec_ctx.bmp.rx_tcam_mem = NULL;
1498 : : }
1499 [ # # ]: 0 : if (sxe2_sctx->ipsec_ctx.bmp.rx_udp_mem != NULL) {
1500 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.rx_udp_mem);
1501 : 0 : sxe2_sctx->ipsec_ctx.bmp.rx_udp_mem = NULL;
1502 : : }
1503 : 0 : l_caps_free:
1504 : 0 : sxe2_cap = &sxe2_sctx->sxe2_capabilities[SXE2_SECURITY_PROTOCOL_IPSEC];
1505 [ # # ]: 0 : if (sxe2_cap->crypto_capabilities != NULL) {
1506 : 0 : rte_free(sxe2_cap->crypto_capabilities);
1507 : 0 : sxe2_cap->crypto_capabilities = NULL;
1508 : : }
1509 : 0 : l_end:
1510 : 0 : return ret;
1511 : : }
1512 : :
1513 : 0 : void sxe2_ipsec_uinit(struct sxe2_adapter *adapter)
1514 : : {
1515 : 0 : struct sxe2_security_ctx *sxe2_sctx = &adapter->security_ctx;
1516 : 0 : struct sxe2_security_capabilities *sxe2_cap =
1517 : : &sxe2_sctx->sxe2_capabilities[SXE2_SECURITY_PROTOCOL_IPSEC];
1518 : 0 : struct sxe2_ipsec_tx_sa *tx_sa = sxe2_sctx->ipsec_ctx.tx_sa;
1519 : 0 : struct sxe2_ipsec_rx_sa *rx_sa = sxe2_sctx->ipsec_ctx.rx_sa;
1520 : 0 : struct sxe2_ipsec_rx_tcam *rx_tcam = sxe2_sctx->ipsec_ctx.rx_tcam;
1521 : 0 : struct sxe2_ipsec_rx_udp_group *rx_udp_group = sxe2_sctx->ipsec_ctx.rx_udp_group;
1522 : :
1523 : 0 : PMD_LOG_INFO(INIT, "Uinit ipsec.");
1524 : :
1525 : 0 : (void)sxe2_drv_ipsec_resource_clear(adapter);
1526 : :
1527 [ # # ]: 0 : if (sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem != NULL) {
1528 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem);
1529 : 0 : sxe2_sctx->ipsec_ctx.bmp.tx_sa_mem = NULL;
1530 : : }
1531 [ # # ]: 0 : if (sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem != NULL) {
1532 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem);
1533 : 0 : sxe2_sctx->ipsec_ctx.bmp.rx_sa_mem = NULL;
1534 : : }
1535 [ # # ]: 0 : if (sxe2_sctx->ipsec_ctx.bmp.rx_tcam_mem != NULL) {
1536 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.rx_tcam_mem);
1537 : 0 : sxe2_sctx->ipsec_ctx.bmp.rx_tcam_mem = NULL;
1538 : : }
1539 [ # # ]: 0 : if (sxe2_sctx->ipsec_ctx.bmp.rx_udp_mem != NULL) {
1540 : 0 : rte_free(sxe2_sctx->ipsec_ctx.bmp.rx_udp_mem);
1541 : 0 : sxe2_sctx->ipsec_ctx.bmp.rx_udp_mem = NULL;
1542 : : }
1543 : :
1544 [ # # ]: 0 : if (tx_sa != NULL) {
1545 : 0 : rte_free(tx_sa);
1546 : 0 : sxe2_sctx->ipsec_ctx.tx_sa = NULL;
1547 : : }
1548 [ # # ]: 0 : if (rx_sa != NULL) {
1549 : 0 : rte_free(rx_sa);
1550 : 0 : sxe2_sctx->ipsec_ctx.rx_sa = NULL;
1551 : : }
1552 [ # # ]: 0 : if (rx_tcam != NULL) {
1553 : 0 : rte_free(rx_tcam);
1554 : 0 : sxe2_sctx->ipsec_ctx.rx_tcam = NULL;
1555 : : }
1556 [ # # ]: 0 : if (rx_udp_group != NULL) {
1557 : 0 : rte_free(rx_udp_group);
1558 : 0 : sxe2_sctx->ipsec_ctx.rx_udp_group = NULL;
1559 : : }
1560 : :
1561 [ # # ]: 0 : if (sxe2_cap->crypto_capabilities != NULL) {
1562 : 0 : rte_free(sxe2_cap->crypto_capabilities);
1563 : 0 : sxe2_cap->crypto_capabilities = NULL;
1564 : : }
1565 : 0 : }
|