Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include <eal_export.h>
6 : : #include <rte_udp.h>
7 : :
8 : : #include "roc_api.h"
9 : :
10 : : #include "cnxk_security.h"
11 : :
12 : : static int
13 : 0 : ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2, uint8_t *cipher_key,
14 : : uint8_t *salt_key, uint8_t *hmac_opad_ipad,
15 : : struct rte_security_ipsec_xform *ipsec_xfrm,
16 : : struct rte_crypto_sym_xform *crypto_xfrm)
17 : : {
18 : : struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm;
19 : : const uint8_t *key = NULL;
20 : : uint8_t ccm_flag = 0;
21 : : uint32_t *tmp_salt;
22 : : uint64_t *tmp_key;
23 : : int i, length = 0;
24 : :
25 : : /* Set direction */
26 [ # # ]: 0 : if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
27 : 0 : w2->s.dir = ROC_IE_SA_DIR_OUTBOUND;
28 : : else
29 : 0 : w2->s.dir = ROC_IE_SA_DIR_INBOUND;
30 : :
31 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
32 : : auth_xfrm = crypto_xfrm;
33 : 0 : cipher_xfrm = crypto_xfrm->next;
34 : : } else {
35 : : cipher_xfrm = crypto_xfrm;
36 : 0 : auth_xfrm = crypto_xfrm->next;
37 : : }
38 : :
39 : : /* Set protocol - ESP vs AH */
40 [ # # # ]: 0 : switch (ipsec_xfrm->proto) {
41 : 0 : case RTE_SECURITY_IPSEC_SA_PROTO_ESP:
42 : 0 : w2->s.protocol = ROC_IE_SA_PROTOCOL_ESP;
43 : 0 : break;
44 : 0 : case RTE_SECURITY_IPSEC_SA_PROTO_AH:
45 : 0 : w2->s.protocol = ROC_IE_SA_PROTOCOL_AH;
46 : 0 : break;
47 : : default:
48 : : return -EINVAL;
49 : : }
50 : :
51 : : /* Set mode - transport vs tunnel */
52 [ # # # ]: 0 : switch (ipsec_xfrm->mode) {
53 : 0 : case RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT:
54 : 0 : w2->s.mode = ROC_IE_SA_MODE_TRANSPORT;
55 : 0 : break;
56 : 0 : case RTE_SECURITY_IPSEC_SA_MODE_TUNNEL:
57 : 0 : w2->s.mode = ROC_IE_SA_MODE_TUNNEL;
58 : 0 : break;
59 : : default:
60 : : return -EINVAL;
61 : : }
62 : :
63 : : /* Set encryption algorithm */
64 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
65 : 0 : key = crypto_xfrm->aead.key.data;
66 : 0 : length = crypto_xfrm->aead.key.length;
67 : :
68 [ # # # ]: 0 : switch (crypto_xfrm->aead.algo) {
69 : 0 : case RTE_CRYPTO_AEAD_AES_GCM:
70 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_AES_GCM;
71 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_NULL;
72 [ # # ]: 0 : memcpy(salt_key, &ipsec_xfrm->salt, 4);
73 : : tmp_salt = (uint32_t *)salt_key;
74 [ # # ]: 0 : *tmp_salt = rte_be_to_cpu_32(*tmp_salt);
75 : 0 : break;
76 : 0 : case RTE_CRYPTO_AEAD_AES_CCM:
77 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_AES_CCM;
78 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_NULL;
79 : : ccm_flag = 0x07 & ~ROC_CPT_AES_CCM_CTR_LEN;
80 : 0 : *salt_key = ccm_flag;
81 [ # # ]: 0 : memcpy(PLT_PTR_ADD(salt_key, 1), &ipsec_xfrm->salt, 3);
82 : : tmp_salt = (uint32_t *)salt_key;
83 [ # # ]: 0 : *tmp_salt = rte_be_to_cpu_32(*tmp_salt);
84 : 0 : break;
85 : : default:
86 : : return -ENOTSUP;
87 : : }
88 : : } else {
89 [ # # ]: 0 : if (cipher_xfrm != NULL) {
90 [ # # # # : 0 : switch (cipher_xfrm->cipher.algo) {
# ]
91 : 0 : case RTE_CRYPTO_CIPHER_NULL:
92 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_NULL;
93 : 0 : break;
94 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
95 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_AES_CBC;
96 : 0 : break;
97 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
98 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_AES_CTR;
99 : 0 : break;
100 : 0 : case RTE_CRYPTO_CIPHER_3DES_CBC:
101 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_3DES_CBC;
102 : 0 : break;
103 : : default:
104 : : return -ENOTSUP;
105 : : }
106 : :
107 : 0 : key = cipher_xfrm->cipher.key.data;
108 : 0 : length = cipher_xfrm->cipher.key.length;
109 : : }
110 : :
111 [ # # # # : 0 : switch (auth_xfrm->auth.algo) {
# # # # ]
112 : 0 : case RTE_CRYPTO_AUTH_NULL:
113 [ # # # # ]: 0 : if (w2->s.dir == ROC_IE_SA_DIR_INBOUND && ipsec_xfrm->replay_win_sz) {
114 : 0 : plt_err("anti-replay can't be supported with integrity service disabled");
115 : 0 : return -EINVAL;
116 : : }
117 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_NULL;
118 : 0 : break;
119 : 0 : case RTE_CRYPTO_AUTH_SHA1_HMAC:
120 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_SHA1;
121 : 0 : break;
122 : 0 : case RTE_CRYPTO_AUTH_SHA256_HMAC:
123 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_SHA2_256;
124 : 0 : break;
125 : 0 : case RTE_CRYPTO_AUTH_SHA384_HMAC:
126 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_SHA2_384;
127 : 0 : break;
128 : 0 : case RTE_CRYPTO_AUTH_SHA512_HMAC:
129 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_SHA2_512;
130 : 0 : break;
131 : 0 : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
132 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_AES_XCBC_128;
133 : 0 : break;
134 : 0 : case RTE_CRYPTO_AUTH_AES_GMAC:
135 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_AES_GMAC;
136 : 0 : key = auth_xfrm->auth.key.data;
137 : 0 : length = auth_xfrm->auth.key.length;
138 [ # # ]: 0 : memcpy(salt_key, &ipsec_xfrm->salt, 4);
139 : : tmp_salt = (uint32_t *)salt_key;
140 [ # # ]: 0 : *tmp_salt = rte_be_to_cpu_32(*tmp_salt);
141 : 0 : break;
142 : : default:
143 : : return -ENOTSUP;
144 : : }
145 : :
146 [ # # ]: 0 : if (auth_xfrm->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) {
147 : 0 : const uint8_t *auth_key = auth_xfrm->auth.key.data;
148 : 0 : roc_aes_xcbc_key_derive(auth_key, hmac_opad_ipad);
149 : : } else {
150 : 0 : roc_se_hmac_opad_ipad_gen(w2->s.auth_type, auth_xfrm->auth.key.data,
151 : 0 : auth_xfrm->auth.key.length, &hmac_opad_ipad[0],
152 : : ROC_SE_IPSEC);
153 : : }
154 : :
155 : : tmp_key = (uint64_t *)hmac_opad_ipad;
156 : : for (i = 0;
157 [ # # ]: 0 : i < (int)(ROC_CTX_MAX_OPAD_IPAD_LEN / sizeof(uint64_t));
158 : 0 : i++)
159 [ # # ]: 0 : tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
160 : :
161 : : }
162 : :
163 : : /* Set encapsulation type */
164 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap)
165 : 0 : w2->s.encap_type = ROC_IE_OT_SA_ENCAP_UDP;
166 : :
167 : 0 : w2->s.spi = ipsec_xfrm->spi;
168 : :
169 [ # # ]: 0 : if (key != NULL && length != 0) {
170 : : /* Copy encryption key */
171 : 0 : memcpy(cipher_key, key, length);
172 : : tmp_key = (uint64_t *)cipher_key;
173 [ # # ]: 0 : for (i = 0; i < (int)(ROC_CTX_MAX_CKEY_LEN / sizeof(uint64_t)); i++)
174 [ # # ]: 0 : tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
175 : : }
176 : :
177 : : /* Set AES key length */
178 : 0 : if (w2->s.enc_type == ROC_IE_SA_ENC_AES_CBC ||
179 : : w2->s.enc_type == ROC_IE_SA_ENC_AES_CTR ||
180 [ # # ]: 0 : w2->s.enc_type == ROC_IE_SA_ENC_AES_GCM ||
181 : 0 : w2->s.enc_type == ROC_IE_SA_ENC_AES_CCM ||
182 [ # # ]: 0 : w2->s.auth_type == ROC_IE_SA_AUTH_AES_GMAC) {
183 [ # # # # ]: 0 : switch (length) {
184 : 0 : case ROC_CPT_AES128_KEY_LEN:
185 : 0 : w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_128;
186 : 0 : break;
187 : 0 : case ROC_CPT_AES192_KEY_LEN:
188 : 0 : w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_192;
189 : 0 : break;
190 : 0 : case ROC_CPT_AES256_KEY_LEN:
191 : 0 : w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_256;
192 : 0 : break;
193 : 0 : default:
194 : 0 : plt_err("Invalid AES key length");
195 : 0 : return -EINVAL;
196 : : }
197 : : }
198 : :
199 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit != 0 ||
200 [ # # ]: 0 : ipsec_xfrm->life.packets_hard_limit != 0) {
201 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
202 [ # # ]: 0 : ipsec_xfrm->life.bytes_hard_limit != 0) {
203 : 0 : plt_err("Expiry tracking with both packets & bytes is not supported");
204 : 0 : return -EINVAL;
205 : : }
206 : 0 : w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_PKTS;
207 : : }
208 : :
209 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
210 [ # # ]: 0 : ipsec_xfrm->life.bytes_hard_limit != 0) {
211 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit != 0 ||
212 [ # # ]: 0 : ipsec_xfrm->life.packets_hard_limit != 0) {
213 : 0 : plt_err("Expiry tracking with both packets & bytes is not supported");
214 : 0 : return -EINVAL;
215 : : }
216 : 0 : w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_OCTETS;
217 : : }
218 : :
219 : : return 0;
220 : : }
221 : :
222 : : static size_t
223 : : ot_ipsec_inb_ctx_size(struct roc_ot_ipsec_inb_sa *sa)
224 : : {
225 : : size_t size;
226 : :
227 : : /* Variable based on Anti-replay Window */
228 : : size = offsetof(struct roc_ot_ipsec_inb_sa, ctx) +
229 : : offsetof(struct roc_ot_ipsec_inb_ctx_update_reg, ar_winbits);
230 : :
231 : 0 : if (sa->w0.s.ar_win)
232 : 0 : size += (1 << (sa->w0.s.ar_win - 1)) * sizeof(uint64_t);
233 : :
234 : : return size;
235 : : }
236 : :
237 : : static void
238 : 0 : ot_ipsec_update_ipv6_addr_endianness(uint64_t *addr)
239 : : {
240 [ # # ]: 0 : *addr = rte_be_to_cpu_64(*addr);
241 : : addr++;
242 [ # # ]: 0 : *addr = rte_be_to_cpu_64(*addr);
243 : 0 : }
244 : :
245 : : static int
246 : 0 : ot_ipsec_inb_tunnel_hdr_fill(struct roc_ot_ipsec_inb_sa *sa,
247 : : struct rte_security_ipsec_xform *ipsec_xfrm)
248 : : {
249 : : struct rte_security_ipsec_tunnel_param *tunnel;
250 : :
251 [ # # ]: 0 : if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
252 : : return 0;
253 : :
254 [ # # ]: 0 : if (ipsec_xfrm->options.tunnel_hdr_verify == 0)
255 : : return 0;
256 : :
257 : : tunnel = &ipsec_xfrm->tunnel;
258 : :
259 [ # # # ]: 0 : switch (tunnel->type) {
260 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV4:
261 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
262 [ # # ]: 0 : memcpy(&sa->outer_hdr.ipv4.src_addr, &tunnel->ipv4.src_ip,
263 : : sizeof(struct in_addr));
264 : 0 : memcpy(&sa->outer_hdr.ipv4.dst_addr, &tunnel->ipv4.dst_ip,
265 : : sizeof(struct in_addr));
266 : :
267 : : /* IP Source and Dest are in LE/CPU endian */
268 : 0 : sa->outer_hdr.ipv4.src_addr =
269 [ # # ]: 0 : rte_be_to_cpu_32(sa->outer_hdr.ipv4.src_addr);
270 : 0 : sa->outer_hdr.ipv4.dst_addr =
271 [ # # ]: 0 : rte_be_to_cpu_32(sa->outer_hdr.ipv4.dst_addr);
272 : :
273 : 0 : break;
274 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV6:
275 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
276 : 0 : memcpy(&sa->outer_hdr.ipv6.src_addr, &tunnel->ipv6.src_addr,
277 : : sizeof(sa->outer_hdr.ipv6.src_addr));
278 : 0 : memcpy(&sa->outer_hdr.ipv6.dst_addr, &tunnel->ipv6.dst_addr,
279 : : sizeof(sa->outer_hdr.ipv6.dst_addr));
280 : :
281 : : /* IP Source and Dest are in LE/CPU endian */
282 : 0 : ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.src_addr);
283 : 0 : ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.dst_addr);
284 : :
285 : 0 : break;
286 : : default:
287 : : return -EINVAL;
288 : : }
289 : :
290 [ # # # ]: 0 : switch (ipsec_xfrm->options.tunnel_hdr_verify) {
291 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR:
292 : 0 : sa->w2.s.ip_hdr_verify = ROC_IE_OT_SA_IP_HDR_VERIFY_DST_ADDR;
293 : 0 : break;
294 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR:
295 : 0 : sa->w2.s.ip_hdr_verify =
296 : : ROC_IE_OT_SA_IP_HDR_VERIFY_SRC_DST_ADDR;
297 : 0 : break;
298 : : default:
299 : : return -ENOTSUP;
300 : : }
301 : :
302 : : return 0;
303 : : }
304 : :
305 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ot_ipsec_inb_sa_fill)
306 : : int
307 : 0 : cnxk_ot_ipsec_inb_sa_fill(struct roc_ot_ipsec_inb_sa *sa,
308 : : struct rte_security_ipsec_xform *ipsec_xfrm,
309 : : struct rte_crypto_sym_xform *crypto_xfrm)
310 : : {
311 : : uint16_t sport = 4500, dport = 4500;
312 : : union roc_ot_ipsec_sa_word2 w2;
313 : : uint32_t replay_win_sz;
314 : : size_t offset;
315 : : int rc;
316 : :
317 : : /* Initialize the SA */
318 : 0 : roc_ot_ipsec_inb_sa_init(sa);
319 : :
320 : 0 : w2.u64 = sa->w2.u64;
321 : 0 : rc = ot_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->w8.s.salt,
322 : 0 : sa->hmac_opad_ipad, ipsec_xfrm,
323 : : crypto_xfrm);
324 [ # # ]: 0 : if (rc)
325 : : return rc;
326 : :
327 : : /* Updata common word2 data */
328 : 0 : sa->w2.u64 = w2.u64;
329 : :
330 : : /* Only support power-of-two window sizes supported */
331 : 0 : replay_win_sz = ipsec_xfrm->replay_win_sz;
332 [ # # ]: 0 : if (replay_win_sz) {
333 [ # # ]: 0 : if (!rte_is_power_of_2(replay_win_sz) ||
334 : : replay_win_sz > ROC_AR_WIN_SIZE_MAX)
335 : : return -ENOTSUP;
336 : :
337 : 0 : sa->w0.s.ar_win = rte_log2_u32(replay_win_sz) - 5;
338 : : }
339 : :
340 : 0 : rc = ot_ipsec_inb_tunnel_hdr_fill(sa, ipsec_xfrm);
341 [ # # ]: 0 : if (rc)
342 : : return rc;
343 : :
344 : : /* Default options for pkt_out and pkt_fmt are with
345 : : * second pass meta and no defrag.
346 : : */
347 : 0 : sa->w0.s.pkt_format = ROC_IE_OT_SA_PKT_FMT_META;
348 : 0 : sa->w0.s.pkt_output = ROC_IE_OT_SA_PKT_OUTPUT_NO_FRAG;
349 : 0 : sa->w0.s.pkind = ROC_IE_OT_CPT_PKIND;
350 : :
351 [ # # ]: 0 : if (ipsec_xfrm->options.ip_reassembly_en)
352 : 0 : sa->w0.s.pkt_output = ROC_IE_OT_SA_PKT_OUTPUT_HW_BASED_DEFRAG;
353 : :
354 : : /* ESN */
355 : 0 : sa->w2.s.esn_en = !!ipsec_xfrm->options.esn;
356 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap) {
357 [ # # ]: 0 : if (ipsec_xfrm->udp.sport)
358 : : sport = ipsec_xfrm->udp.sport;
359 : :
360 [ # # ]: 0 : if (ipsec_xfrm->udp.dport)
361 : : dport = ipsec_xfrm->udp.dport;
362 : :
363 : 0 : sa->w10.s.udp_src_port = sport;
364 : 0 : sa->w10.s.udp_dst_port = dport;
365 : : }
366 : :
367 [ # # ]: 0 : if (ipsec_xfrm->options.udp_ports_verify)
368 : 0 : sa->w2.s.udp_ports_verify = 1;
369 : :
370 : : offset = offsetof(struct roc_ot_ipsec_inb_sa, ctx);
371 : : /* Word offset for HW managed SA field */
372 : 0 : sa->w0.s.hw_ctx_off = offset / 8;
373 : : /* Context push size for inbound spans up to hw_ctx including
374 : : * ar_base field, in 8b units
375 : : */
376 [ # # ]: 0 : sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off + 1;
377 : : /* Entire context size in 128B units */
378 : 0 : sa->w0.s.ctx_size =
379 : 0 : (PLT_ALIGN_CEIL(ot_ipsec_inb_ctx_size(sa), ROC_CTX_UNIT_128B) /
380 : 0 : ROC_CTX_UNIT_128B) -
381 : : 1;
382 : :
383 : : /**
384 : : * CPT MC triggers expiry when counter value changes from 2 to 1. To
385 : : * mitigate this behaviour add 1 to the life counter values provided.
386 : : */
387 : :
388 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit) {
389 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
390 : 0 : sa->w0.s.soft_life_dec = 1;
391 : : }
392 : :
393 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit) {
394 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
395 : 0 : sa->w0.s.soft_life_dec = 1;
396 : : }
397 : :
398 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_hard_limit) {
399 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
400 : 0 : sa->w0.s.hard_life_dec = 1;
401 : : }
402 : :
403 [ # # ]: 0 : if (ipsec_xfrm->life.packets_hard_limit) {
404 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
405 : 0 : sa->w0.s.hard_life_dec = 1;
406 : : }
407 : :
408 : : rte_wmb();
409 : :
410 : : /* Enable SA */
411 : 0 : sa->w2.s.valid = 1;
412 : 0 : return 0;
413 : : }
414 : :
415 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ot_ipsec_outb_sa_fill)
416 : : int
417 : 0 : cnxk_ot_ipsec_outb_sa_fill(struct roc_ot_ipsec_outb_sa *sa,
418 : : struct rte_security_ipsec_xform *ipsec_xfrm,
419 : : struct rte_crypto_sym_xform *crypto_xfrm)
420 : : {
421 : : struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel;
422 : : uint16_t sport = 4500, dport = 4500;
423 : : union roc_ot_ipsec_sa_word2 w2;
424 : : size_t offset;
425 : : int rc;
426 : :
427 : : /* Initialize the SA */
428 : 0 : roc_ot_ipsec_outb_sa_init(sa);
429 : :
430 : 0 : w2.u64 = 0;
431 : 0 : rc = ot_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->iv.s.salt,
432 : 0 : sa->hmac_opad_ipad, ipsec_xfrm,
433 : : crypto_xfrm);
434 [ # # ]: 0 : if (rc)
435 : : return rc;
436 : :
437 : : /* Update common word2 data */
438 : 0 : sa->w2.u64 = w2.u64;
439 : :
440 [ # # ]: 0 : if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
441 : 0 : goto skip_tunnel_info;
442 : :
443 : : /* Tunnel header info */
444 [ # # # ]: 0 : switch (tunnel->type) {
445 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV4:
446 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
447 [ # # ]: 0 : memcpy(&sa->outer_hdr.ipv4.src_addr, &tunnel->ipv4.src_ip,
448 : : sizeof(struct in_addr));
449 : 0 : memcpy(&sa->outer_hdr.ipv4.dst_addr, &tunnel->ipv4.dst_ip,
450 : : sizeof(struct in_addr));
451 : :
452 : : /* IP Source and Dest seems to be in LE/CPU endian */
453 : 0 : sa->outer_hdr.ipv4.src_addr =
454 [ # # ]: 0 : rte_be_to_cpu_32(sa->outer_hdr.ipv4.src_addr);
455 : 0 : sa->outer_hdr.ipv4.dst_addr =
456 [ # # ]: 0 : rte_be_to_cpu_32(sa->outer_hdr.ipv4.dst_addr);
457 : :
458 : : /* Outer header DF bit source */
459 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_df) {
460 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
461 : : ROC_IE_OT_SA_COPY_FROM_SA;
462 : 0 : sa->w10.s.ipv4_df_or_ipv6_flw_lbl = tunnel->ipv4.df;
463 : : } else {
464 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
465 : : ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
466 : : }
467 : :
468 : : /* Outer header DSCP source */
469 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_dscp) {
470 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_SA;
471 : 0 : sa->w10.s.dscp = tunnel->ipv4.dscp;
472 : : } else {
473 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
474 : : }
475 : : break;
476 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV6:
477 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
478 : 0 : memcpy(&sa->outer_hdr.ipv6.src_addr, &tunnel->ipv6.src_addr,
479 : : sizeof(sa->outer_hdr.ipv6.src_addr));
480 : 0 : memcpy(&sa->outer_hdr.ipv6.dst_addr, &tunnel->ipv6.dst_addr,
481 : : sizeof(sa->outer_hdr.ipv6.dst_addr));
482 : :
483 : : /* IP Source and Dest are in LE/CPU endian */
484 : 0 : ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.src_addr);
485 : 0 : ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.dst_addr);
486 : :
487 : : /* Outer header flow label source */
488 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_flabel) {
489 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
490 : : ROC_IE_OT_SA_COPY_FROM_SA;
491 : :
492 : 0 : sa->w10.s.ipv4_df_or_ipv6_flw_lbl = tunnel->ipv6.flabel;
493 : : } else {
494 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
495 : : ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
496 : : }
497 : :
498 : : /* Outer header DSCP source */
499 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_dscp) {
500 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_SA;
501 : 0 : sa->w10.s.dscp = tunnel->ipv6.dscp;
502 : : } else {
503 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
504 : : }
505 : : break;
506 : : default:
507 : : return -EINVAL;
508 : : }
509 : :
510 : 0 : skip_tunnel_info:
511 : : /* ESN */
512 : 0 : sa->w0.s.esn_en = !!ipsec_xfrm->options.esn;
513 : :
514 [ # # ]: 0 : if (ipsec_xfrm->esn.value)
515 : 0 : sa->ctx.esn_val = ipsec_xfrm->esn.value - 1;
516 : :
517 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap) {
518 [ # # ]: 0 : if (ipsec_xfrm->udp.sport)
519 : : sport = ipsec_xfrm->udp.sport;
520 : :
521 [ # # ]: 0 : if (ipsec_xfrm->udp.dport)
522 : : dport = ipsec_xfrm->udp.dport;
523 : :
524 : 0 : sa->w10.s.udp_src_port = sport;
525 : 0 : sa->w10.s.udp_dst_port = dport;
526 : : }
527 : :
528 : : offset = offsetof(struct roc_ot_ipsec_outb_sa, ctx);
529 : : /* Word offset for HW managed SA field */
530 : 0 : sa->w0.s.hw_ctx_off = offset / 8;
531 : :
532 : : /* Context push size is up to err ctl in HW ctx */
533 : 0 : sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off + 1;
534 : :
535 : : /* Entire context size in 128B units */
536 : : offset = sizeof(struct roc_ot_ipsec_outb_sa);
537 : 0 : sa->w0.s.ctx_size = (PLT_ALIGN_CEIL(offset, ROC_CTX_UNIT_128B) /
538 : : ROC_CTX_UNIT_128B) -
539 : : 1;
540 : :
541 : : /* IPID gen */
542 : 0 : sa->w2.s.ipid_gen = 1;
543 : :
544 : : /**
545 : : * CPT MC triggers expiry when counter value changes from 2 to 1. To
546 : : * mitigate this behaviour add 1 to the life counter values provided.
547 : : */
548 : :
549 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit) {
550 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
551 : 0 : sa->w0.s.soft_life_dec = 1;
552 : : }
553 : :
554 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit) {
555 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
556 : 0 : sa->w0.s.soft_life_dec = 1;
557 : : }
558 : :
559 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_hard_limit) {
560 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
561 : 0 : sa->w0.s.hard_life_dec = 1;
562 : : }
563 : :
564 [ # # ]: 0 : if (ipsec_xfrm->life.packets_hard_limit) {
565 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
566 : 0 : sa->w0.s.hard_life_dec = 1;
567 : : }
568 : :
569 : : /* There are two words of CPT_CTX_HW_S for ucode to skip */
570 : 0 : sa->w0.s.ctx_hdr_size = 1;
571 : 0 : sa->w0.s.aop_valid = 1;
572 : :
573 : : rte_wmb();
574 : :
575 : : /* Enable SA */
576 : 0 : sa->w2.s.valid = 1;
577 : 0 : return 0;
578 : : }
579 : :
580 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ot_ipsec_inb_sa_valid)
581 : : bool
582 : 0 : cnxk_ot_ipsec_inb_sa_valid(struct roc_ot_ipsec_inb_sa *sa)
583 : : {
584 : 0 : return !!sa->w2.s.valid;
585 : : }
586 : :
587 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ot_ipsec_outb_sa_valid)
588 : : bool
589 : 0 : cnxk_ot_ipsec_outb_sa_valid(struct roc_ot_ipsec_outb_sa *sa)
590 : : {
591 : 0 : return !!sa->w2.s.valid;
592 : : }
593 : :
594 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ipsec_ivlen_get)
595 : : uint8_t
596 : 0 : cnxk_ipsec_ivlen_get(enum rte_crypto_cipher_algorithm c_algo,
597 : : enum rte_crypto_auth_algorithm a_algo,
598 : : enum rte_crypto_aead_algorithm aead_algo)
599 : : {
600 : : uint8_t ivlen = 0;
601 : :
602 [ # # ]: 0 : if ((aead_algo == RTE_CRYPTO_AEAD_AES_GCM) || (aead_algo == RTE_CRYPTO_AEAD_AES_CCM))
603 : : ivlen = 8;
604 : :
605 [ # # # # ]: 0 : switch (c_algo) {
606 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
607 : : ivlen = 8;
608 : 0 : break;
609 : 0 : case RTE_CRYPTO_CIPHER_DES_CBC:
610 : : case RTE_CRYPTO_CIPHER_3DES_CBC:
611 : : ivlen = ROC_CPT_DES_BLOCK_LENGTH;
612 : 0 : break;
613 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
614 : : ivlen = ROC_CPT_AES_BLOCK_LENGTH;
615 : 0 : break;
616 : : default:
617 : : break;
618 : : }
619 : :
620 [ # # ]: 0 : switch (a_algo) {
621 : 0 : case RTE_CRYPTO_AUTH_AES_GMAC:
622 : : ivlen = 8;
623 : 0 : break;
624 : : default:
625 : : break;
626 : : }
627 : :
628 : 0 : return ivlen;
629 : : }
630 : :
631 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ipsec_icvlen_get)
632 : : uint8_t
633 [ # # ]: 0 : cnxk_ipsec_icvlen_get(enum rte_crypto_cipher_algorithm c_algo,
634 : : enum rte_crypto_auth_algorithm a_algo,
635 : : enum rte_crypto_aead_algorithm aead_algo)
636 : : {
637 : : uint8_t icv = 0;
638 : :
639 : : (void)c_algo;
640 : :
641 : : switch (a_algo) {
642 : : case RTE_CRYPTO_AUTH_NULL:
643 : : icv = 0;
644 : : break;
645 : : case RTE_CRYPTO_AUTH_MD5_HMAC:
646 : : case RTE_CRYPTO_AUTH_SHA1_HMAC:
647 : : icv = 12;
648 : : break;
649 : : case RTE_CRYPTO_AUTH_SHA256_HMAC:
650 : : case RTE_CRYPTO_AUTH_AES_GMAC:
651 : : icv = 16;
652 : : break;
653 : : case RTE_CRYPTO_AUTH_SHA384_HMAC:
654 : : icv = 24;
655 : : break;
656 : : case RTE_CRYPTO_AUTH_SHA512_HMAC:
657 : : icv = 32;
658 : : break;
659 : : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
660 : : icv = 12;
661 : : break;
662 : : default:
663 : : break;
664 : : }
665 : :
666 [ # # ]: 0 : switch (aead_algo) {
667 : 0 : case RTE_CRYPTO_AEAD_AES_GCM:
668 : : case RTE_CRYPTO_AEAD_AES_CCM:
669 : : icv = 16;
670 : 0 : break;
671 : : default:
672 : : break;
673 : : }
674 : :
675 : 0 : return icv;
676 : : }
677 : :
678 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ipsec_outb_roundup_byte)
679 : : uint8_t
680 : 0 : cnxk_ipsec_outb_roundup_byte(enum rte_crypto_cipher_algorithm c_algo,
681 : : enum rte_crypto_aead_algorithm aead_algo)
682 : : {
683 : : uint8_t roundup_byte = 4;
684 : :
685 [ # # ]: 0 : if ((aead_algo == RTE_CRYPTO_AEAD_AES_GCM) || (aead_algo == RTE_CRYPTO_AEAD_AES_CCM))
686 : : return roundup_byte;
687 : :
688 [ # # # ]: 0 : switch (c_algo) {
689 : : case RTE_CRYPTO_CIPHER_AES_CTR:
690 : : roundup_byte = 4;
691 : : break;
692 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
693 : : roundup_byte = 16;
694 : 0 : break;
695 : 0 : case RTE_CRYPTO_CIPHER_DES_CBC:
696 : : case RTE_CRYPTO_CIPHER_3DES_CBC:
697 : : roundup_byte = 8;
698 : 0 : break;
699 : : case RTE_CRYPTO_CIPHER_NULL:
700 : : roundup_byte = 4;
701 : : break;
702 : : default:
703 : : break;
704 : : }
705 : :
706 : : return roundup_byte;
707 : : }
708 : :
709 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ipsec_outb_rlens_get)
710 : : int
711 [ # # ]: 0 : cnxk_ipsec_outb_rlens_get(struct cnxk_ipsec_outb_rlens *rlens,
712 : : struct rte_security_ipsec_xform *ipsec_xfrm,
713 : : struct rte_crypto_sym_xform *crypto_xfrm)
714 : : {
715 : : struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel;
716 : : enum rte_crypto_cipher_algorithm c_algo = RTE_CRYPTO_CIPHER_NULL;
717 : : enum rte_crypto_auth_algorithm a_algo = RTE_CRYPTO_AUTH_NULL;
718 : : enum rte_crypto_aead_algorithm aead_algo = 0;
719 : : uint16_t partial_len = 0;
720 : : uint8_t roundup_byte = 0;
721 : : int8_t roundup_len = 0;
722 : :
723 : : memset(rlens, 0, sizeof(struct cnxk_ipsec_outb_rlens));
724 : :
725 : : /* Get Cipher and Auth algo */
726 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
727 : 0 : aead_algo = crypto_xfrm->aead.algo;
728 : : } else {
729 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
730 : 0 : c_algo = crypto_xfrm->cipher.algo;
731 : : else
732 : 0 : a_algo = crypto_xfrm->auth.algo;
733 : :
734 [ # # ]: 0 : if (crypto_xfrm->next) {
735 [ # # ]: 0 : if (crypto_xfrm->next->type ==
736 : : RTE_CRYPTO_SYM_XFORM_CIPHER)
737 : 0 : c_algo = crypto_xfrm->next->cipher.algo;
738 : : else
739 : 0 : a_algo = crypto_xfrm->next->auth.algo;
740 : : }
741 : : }
742 : :
743 [ # # ]: 0 : if (ipsec_xfrm->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) {
744 : : partial_len = ROC_CPT_ESP_HDR_LEN;
745 : : roundup_len = ROC_CPT_ESP_TRL_LEN;
746 : : } else {
747 : : partial_len = ROC_CPT_AH_HDR_LEN;
748 : : }
749 : :
750 [ # # ]: 0 : if (ipsec_xfrm->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
751 [ # # ]: 0 : if (tunnel->type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
752 : 0 : partial_len += ROC_CPT_TUNNEL_IPV4_HDR_LEN;
753 : : else
754 : 0 : partial_len += ROC_CPT_TUNNEL_IPV6_HDR_LEN;
755 : : }
756 : :
757 : 0 : partial_len += cnxk_ipsec_ivlen_get(c_algo, a_algo, aead_algo);
758 : 0 : partial_len += cnxk_ipsec_icvlen_get(c_algo, a_algo, aead_algo);
759 : 0 : roundup_byte = cnxk_ipsec_outb_roundup_byte(c_algo, aead_algo);
760 : :
761 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap)
762 : 0 : partial_len += sizeof(struct rte_udp_hdr);
763 : :
764 : 0 : rlens->partial_len = partial_len;
765 : 0 : rlens->roundup_len = roundup_len;
766 : 0 : rlens->roundup_byte = roundup_byte;
767 : 0 : rlens->max_extended_len = partial_len + roundup_len + roundup_byte;
768 : 0 : return 0;
769 : : }
770 : :
771 : : static inline int
772 : 0 : on_ipsec_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
773 : : struct rte_crypto_sym_xform *crypto_xform,
774 : : struct roc_ie_on_sa_ctl *ctl)
775 : : {
776 : : struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
777 : : int aes_key_len = 0;
778 : :
779 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
780 : : auth_xform = crypto_xform;
781 : 0 : cipher_xform = crypto_xform->next;
782 : : } else {
783 : : cipher_xform = crypto_xform;
784 : 0 : auth_xform = crypto_xform->next;
785 : : }
786 : :
787 [ # # ]: 0 : if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
788 : 0 : ctl->direction = ROC_IE_SA_DIR_OUTBOUND;
789 : : else
790 : 0 : ctl->direction = ROC_IE_SA_DIR_INBOUND;
791 : :
792 [ # # ]: 0 : if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
793 [ # # ]: 0 : if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
794 : 0 : ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
795 [ # # ]: 0 : else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
796 : 0 : ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
797 : : else
798 : : return -EINVAL;
799 : : }
800 : :
801 [ # # ]: 0 : if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) {
802 : 0 : ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT;
803 : 0 : ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
804 [ # # ]: 0 : } else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
805 : 0 : ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL;
806 : : else
807 : : return -EINVAL;
808 : :
809 [ # # ]: 0 : if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
810 : 0 : ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_AH;
811 [ # # ]: 0 : else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP)
812 : 0 : ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP;
813 : : else
814 : : return -EINVAL;
815 : :
816 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
817 [ # # # ]: 0 : switch (crypto_xform->aead.algo) {
818 : 0 : case RTE_CRYPTO_AEAD_AES_GCM:
819 : 0 : ctl->enc_type = ROC_IE_SA_ENC_AES_GCM;
820 : 0 : aes_key_len = crypto_xform->aead.key.length;
821 : 0 : break;
822 : 0 : case RTE_CRYPTO_AEAD_AES_CCM:
823 : 0 : ctl->enc_type = ROC_IE_SA_ENC_AES_CCM;
824 : 0 : aes_key_len = crypto_xform->aead.key.length;
825 : 0 : break;
826 : 0 : default:
827 : 0 : plt_err("Unsupported AEAD algorithm");
828 : 0 : return -ENOTSUP;
829 : : }
830 : : } else {
831 [ # # ]: 0 : if (cipher_xform != NULL) {
832 [ # # # # : 0 : switch (cipher_xform->cipher.algo) {
# # ]
833 : 0 : case RTE_CRYPTO_CIPHER_NULL:
834 : 0 : ctl->enc_type = ROC_IE_SA_ENC_NULL;
835 : 0 : break;
836 : 0 : case RTE_CRYPTO_CIPHER_DES_CBC:
837 : 0 : ctl->enc_type = ROC_IE_SA_ENC_DES_CBC;
838 : 0 : break;
839 : 0 : case RTE_CRYPTO_CIPHER_3DES_CBC:
840 : 0 : ctl->enc_type = ROC_IE_SA_ENC_3DES_CBC;
841 : 0 : break;
842 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
843 : 0 : ctl->enc_type = ROC_IE_SA_ENC_AES_CBC;
844 : 0 : aes_key_len = cipher_xform->cipher.key.length;
845 : 0 : break;
846 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
847 : 0 : ctl->enc_type = ROC_IE_SA_ENC_AES_CTR;
848 : 0 : aes_key_len = cipher_xform->cipher.key.length;
849 : 0 : break;
850 : 0 : default:
851 : 0 : plt_err("Unsupported cipher algorithm");
852 : 0 : return -ENOTSUP;
853 : : }
854 : : }
855 : :
856 [ # # # # : 0 : switch (auth_xform->auth.algo) {
# # # # #
# ]
857 : 0 : case RTE_CRYPTO_AUTH_NULL:
858 : 0 : ctl->auth_type = ROC_IE_SA_AUTH_NULL;
859 : 0 : break;
860 : 0 : case RTE_CRYPTO_AUTH_MD5_HMAC:
861 : 0 : ctl->auth_type = ROC_IE_SA_AUTH_MD5;
862 : 0 : break;
863 : 0 : case RTE_CRYPTO_AUTH_SHA1_HMAC:
864 : 0 : ctl->auth_type = ROC_IE_SA_AUTH_SHA1;
865 : 0 : break;
866 : 0 : case RTE_CRYPTO_AUTH_SHA224_HMAC:
867 : 0 : ctl->auth_type = ROC_IE_SA_AUTH_SHA2_224;
868 : 0 : break;
869 : 0 : case RTE_CRYPTO_AUTH_SHA256_HMAC:
870 : 0 : ctl->auth_type = ROC_IE_SA_AUTH_SHA2_256;
871 : 0 : break;
872 : 0 : case RTE_CRYPTO_AUTH_SHA384_HMAC:
873 : 0 : ctl->auth_type = ROC_IE_SA_AUTH_SHA2_384;
874 : 0 : break;
875 : 0 : case RTE_CRYPTO_AUTH_SHA512_HMAC:
876 : 0 : ctl->auth_type = ROC_IE_SA_AUTH_SHA2_512;
877 : 0 : break;
878 : 0 : case RTE_CRYPTO_AUTH_AES_GMAC:
879 : 0 : ctl->auth_type = ROC_IE_SA_AUTH_AES_GMAC;
880 : 0 : aes_key_len = auth_xform->auth.key.length;
881 : 0 : break;
882 : 0 : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
883 : 0 : ctl->auth_type = ROC_IE_SA_AUTH_AES_XCBC_128;
884 : 0 : break;
885 : 0 : default:
886 : 0 : plt_err("Unsupported auth algorithm");
887 : 0 : return -ENOTSUP;
888 : : }
889 : : }
890 : :
891 : : /* Set AES key length */
892 : 0 : if (ctl->enc_type == ROC_IE_SA_ENC_AES_CBC ||
893 : : ctl->enc_type == ROC_IE_SA_ENC_AES_CTR ||
894 [ # # ]: 0 : ctl->enc_type == ROC_IE_SA_ENC_AES_GCM ||
895 : 0 : ctl->enc_type == ROC_IE_SA_ENC_AES_CCM ||
896 [ # # ]: 0 : ctl->auth_type == ROC_IE_SA_AUTH_AES_GMAC) {
897 [ # # # # ]: 0 : switch (aes_key_len) {
898 : 0 : case 16:
899 : 0 : ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128;
900 : 0 : break;
901 : 0 : case 24:
902 : 0 : ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192;
903 : 0 : break;
904 : 0 : case 32:
905 : 0 : ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256;
906 : 0 : break;
907 : 0 : default:
908 : 0 : plt_err("Invalid AES key length");
909 : 0 : return -EINVAL;
910 : : }
911 : : }
912 : :
913 [ # # ]: 0 : if (ipsec->options.esn)
914 : 0 : ctl->esn_en = 1;
915 : :
916 [ # # ]: 0 : if (ipsec->options.udp_encap == 1)
917 : 0 : ctl->encap_type = ROC_IE_ON_SA_ENCAP_UDP;
918 : :
919 : 0 : ctl->copy_df = ipsec->options.copy_df;
920 : :
921 [ # # ]: 0 : ctl->spi = rte_cpu_to_be_32(ipsec->spi);
922 : :
923 : 0 : rte_io_wmb();
924 : :
925 : 0 : ctl->valid = 1;
926 : :
927 : 0 : return 0;
928 : : }
929 : :
930 : : static inline int
931 : 0 : on_fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec,
932 : : struct rte_crypto_sym_xform *crypto_xform,
933 : : struct roc_ie_on_common_sa *common_sa)
934 : : {
935 : : struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
936 : : const uint8_t *cipher_key;
937 : : int cipher_key_len = 0;
938 : : uint8_t ccm_flag = 0;
939 : : int ret;
940 : :
941 : 0 : ret = on_ipsec_sa_ctl_set(ipsec, crypto_xform, &common_sa->ctl);
942 [ # # ]: 0 : if (ret)
943 : : return ret;
944 : :
945 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
946 : : auth_xform = crypto_xform;
947 : 0 : cipher_xform = crypto_xform->next;
948 : : } else {
949 : : cipher_xform = crypto_xform;
950 : 0 : auth_xform = crypto_xform->next;
951 : : }
952 : :
953 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
954 [ # # ]: 0 : if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM)
955 : 0 : memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4);
956 [ # # ]: 0 : else if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM) {
957 : : ccm_flag = 0x07 & ~ROC_CPT_AES_CCM_CTR_LEN;
958 : 0 : *common_sa->iv.gcm.nonce = ccm_flag;
959 : 0 : memcpy(PLT_PTR_ADD(common_sa->iv.gcm.nonce, 1), &ipsec->salt, 3);
960 : : }
961 : 0 : cipher_key = crypto_xform->aead.key.data;
962 : 0 : cipher_key_len = crypto_xform->aead.key.length;
963 : : } else {
964 [ # # ]: 0 : if (cipher_xform) {
965 : 0 : cipher_key = cipher_xform->cipher.key.data;
966 : 0 : cipher_key_len = cipher_xform->cipher.key.length;
967 : : }
968 : :
969 [ # # ]: 0 : if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
970 : 0 : memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4);
971 : 0 : cipher_key = auth_xform->auth.key.data;
972 : 0 : cipher_key_len = auth_xform->auth.key.length;
973 : : }
974 : : }
975 : :
976 [ # # ]: 0 : if (cipher_key_len != 0)
977 : 0 : memcpy(common_sa->cipher_key, cipher_key, cipher_key_len);
978 : :
979 : : return 0;
980 : : }
981 : :
982 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_on_ipsec_outb_sa_create)
983 : : int
984 : 0 : cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec,
985 : : struct rte_crypto_sym_xform *crypto_xform,
986 : : struct roc_ie_on_outb_sa *out_sa)
987 : : {
988 : : struct roc_ie_on_ip_template *template = NULL;
989 : : struct rte_crypto_sym_xform *auth_xform;
990 : : struct roc_ie_on_sa_ctl *ctl;
991 : : struct rte_ipv6_hdr *ip6;
992 : : struct rte_ipv4_hdr *ip4;
993 : : uint16_t sport, dport;
994 : : size_t ctx_len;
995 : : int ret;
996 : :
997 : : ctl = &out_sa->common_sa.ctl;
998 : :
999 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH)
1000 : : auth_xform = crypto_xform;
1001 : : else
1002 : 0 : auth_xform = crypto_xform->next;
1003 : :
1004 : 0 : ret = on_fill_ipsec_common_sa(ipsec, crypto_xform, &out_sa->common_sa);
1005 [ # # ]: 0 : if (ret)
1006 : : return ret;
1007 : :
1008 [ # # ]: 0 : if (ctl->enc_type == ROC_IE_SA_ENC_AES_GCM || ctl->enc_type == ROC_IE_SA_ENC_AES_CCM ||
1009 [ # # # # ]: 0 : ctl->auth_type == ROC_IE_SA_AUTH_NULL || ctl->auth_type == ROC_IE_SA_AUTH_AES_GMAC) {
1010 : 0 : template = &out_sa->aes_gcm.template;
1011 : 0 : ctx_len = offsetof(struct roc_ie_on_outb_sa, aes_gcm.template);
1012 : : } else {
1013 [ # # # # ]: 0 : switch (ctl->auth_type) {
1014 : 0 : case ROC_IE_SA_AUTH_MD5:
1015 : : case ROC_IE_SA_AUTH_SHA1:
1016 : 0 : template = &out_sa->sha1.template;
1017 : : ctx_len = offsetof(struct roc_ie_on_outb_sa, sha1.template);
1018 : 0 : break;
1019 : 0 : case ROC_IE_SA_AUTH_SHA2_256:
1020 : : case ROC_IE_SA_AUTH_SHA2_384:
1021 : : case ROC_IE_SA_AUTH_SHA2_512:
1022 : 0 : template = &out_sa->sha2.template;
1023 : : ctx_len = offsetof(struct roc_ie_on_outb_sa, sha2.template);
1024 : 0 : break;
1025 : 0 : case ROC_IE_SA_AUTH_AES_XCBC_128:
1026 : 0 : template = &out_sa->aes_xcbc.template;
1027 : : ctx_len = offsetof(struct roc_ie_on_outb_sa, aes_xcbc.template);
1028 : 0 : break;
1029 : 0 : default:
1030 : 0 : plt_err("Unsupported auth algorithm");
1031 : 0 : return -EINVAL;
1032 : : }
1033 : : }
1034 : :
1035 : : ip4 = (struct rte_ipv4_hdr *)&template->ip4.ipv4_hdr;
1036 : :
1037 : : sport = 4500;
1038 : : dport = 4500;
1039 : :
1040 : : /* If custom port values are provided, Overwrite default port values. */
1041 [ # # ]: 0 : if (ipsec->options.udp_encap) {
1042 : :
1043 [ # # ]: 0 : if (ipsec->udp.sport)
1044 : : sport = ipsec->udp.sport;
1045 : :
1046 [ # # ]: 0 : if (ipsec->udp.dport)
1047 : : dport = ipsec->udp.dport;
1048 : :
1049 : 0 : ip4->next_proto_id = IPPROTO_UDP;
1050 [ # # ]: 0 : template->ip4.udp_src = rte_be_to_cpu_16(sport);
1051 [ # # ]: 0 : template->ip4.udp_dst = rte_be_to_cpu_16(dport);
1052 : : } else {
1053 [ # # ]: 0 : if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
1054 : 0 : ip4->next_proto_id = IPPROTO_AH;
1055 : : else
1056 : 0 : ip4->next_proto_id = IPPROTO_ESP;
1057 : : }
1058 : :
1059 [ # # ]: 0 : if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
1060 [ # # ]: 0 : if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
1061 : : uint16_t frag_off = 0;
1062 : :
1063 : 0 : ctx_len += sizeof(template->ip4);
1064 : :
1065 : 0 : ip4->version_ihl = RTE_IPV4_VHL_DEF;
1066 [ # # ]: 0 : ip4->time_to_live = ipsec->tunnel.ipv4.ttl ?
1067 : : ipsec->tunnel.ipv4.ttl :
1068 : : 0x40;
1069 : 0 : ip4->type_of_service |= (ipsec->tunnel.ipv4.dscp << 2);
1070 [ # # ]: 0 : if (ipsec->tunnel.ipv4.df)
1071 : : frag_off |= RTE_IPV4_HDR_DF_FLAG;
1072 [ # # ]: 0 : ip4->fragment_offset = rte_cpu_to_be_16(frag_off);
1073 : :
1074 : 0 : memcpy(&ip4->src_addr, &ipsec->tunnel.ipv4.src_ip,
1075 : : sizeof(struct in_addr));
1076 : 0 : memcpy(&ip4->dst_addr, &ipsec->tunnel.ipv4.dst_ip,
1077 : : sizeof(struct in_addr));
1078 [ # # ]: 0 : } else if (ipsec->tunnel.type ==
1079 : : RTE_SECURITY_IPSEC_TUNNEL_IPV6) {
1080 : 0 : ctx_len += sizeof(template->ip6);
1081 : :
1082 : : ip6 = (struct rte_ipv6_hdr *)&template->ip6.ipv6_hdr;
1083 [ # # ]: 0 : if (ipsec->options.udp_encap) {
1084 : 0 : ip6->proto = IPPROTO_UDP;
1085 [ # # ]: 0 : template->ip6.udp_src = rte_be_to_cpu_16(sport);
1086 [ # # ]: 0 : template->ip6.udp_dst = rte_be_to_cpu_16(dport);
1087 : : } else {
1088 [ # # ]: 0 : ip6->proto = (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) ?
1089 : : IPPROTO_ESP :
1090 : : IPPROTO_AH;
1091 : : }
1092 : 0 : ip6->vtc_flow =
1093 [ # # ]: 0 : rte_cpu_to_be_32(0x60000000 |
1094 : : ((ipsec->tunnel.ipv6.dscp
1095 : : << RTE_IPV6_HDR_TC_SHIFT) &
1096 : : RTE_IPV6_HDR_TC_MASK) |
1097 : : ((ipsec->tunnel.ipv6.flabel
1098 : : << RTE_IPV6_HDR_FL_SHIFT) &
1099 : : RTE_IPV6_HDR_FL_MASK));
1100 [ # # ]: 0 : ip6->hop_limits = ipsec->tunnel.ipv6.hlimit ?
1101 : : ipsec->tunnel.ipv6.hlimit :
1102 : : 0x40;
1103 : 0 : ip6->src_addr = ipsec->tunnel.ipv6.src_addr;
1104 : 0 : ip6->dst_addr = ipsec->tunnel.ipv6.dst_addr;
1105 : : }
1106 : : } else
1107 : 0 : ctx_len += sizeof(template->ip4);
1108 : :
1109 : 0 : ctx_len = RTE_ALIGN_CEIL(ctx_len, 8);
1110 : :
1111 [ # # ]: 0 : if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
1112 : 0 : uint8_t *hmac_opad_ipad = (uint8_t *)&out_sa->sha2;
1113 : :
1114 [ # # ]: 0 : if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) {
1115 : 0 : const uint8_t *auth_key = auth_xform->auth.key.data;
1116 : :
1117 : 0 : roc_aes_xcbc_key_derive(auth_key, hmac_opad_ipad);
1118 [ # # ]: 0 : } else if (auth_xform->auth.algo != RTE_CRYPTO_AUTH_NULL) {
1119 : 0 : roc_se_hmac_opad_ipad_gen(
1120 : 0 : out_sa->common_sa.ctl.auth_type, auth_xform->auth.key.data,
1121 : 0 : auth_xform->auth.key.length, &hmac_opad_ipad[0], ROC_SE_IPSEC);
1122 : : }
1123 : : }
1124 : :
1125 : 0 : return ctx_len;
1126 : : }
1127 : :
1128 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_on_ipsec_inb_sa_create)
1129 : : int
1130 : 0 : cnxk_on_ipsec_inb_sa_create(struct rte_security_ipsec_xform *ipsec,
1131 : : struct rte_crypto_sym_xform *crypto_xform,
1132 : : struct roc_ie_on_inb_sa *in_sa)
1133 : : {
1134 : : struct rte_crypto_sym_xform *auth_xform = crypto_xform;
1135 : : const uint8_t *auth_key;
1136 : : int auth_key_len = 0;
1137 : : size_t ctx_len = 0;
1138 : : int ret;
1139 : :
1140 : 0 : ret = on_fill_ipsec_common_sa(ipsec, crypto_xform, &in_sa->common_sa);
1141 [ # # ]: 0 : if (ret)
1142 : : return ret;
1143 : :
1144 [ # # ]: 0 : if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD &&
1145 [ # # # # ]: 0 : crypto_xform->auth.algo == RTE_CRYPTO_AUTH_NULL && ipsec->replay_win_sz) {
1146 : 0 : plt_err("anti-replay can't be supported with integrity service disabled");
1147 : 0 : return -EINVAL;
1148 : : }
1149 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD ||
1150 [ # # # # ]: 0 : auth_xform->auth.algo == RTE_CRYPTO_AUTH_NULL ||
1151 : : auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
1152 : : ctx_len = offsetof(struct roc_ie_on_inb_sa, sha1_or_gcm.hmac_key[0]);
1153 : : } else {
1154 : 0 : uint8_t *hmac_opad_ipad = (uint8_t *)&in_sa->sha2;
1155 : 0 : auth_key = auth_xform->auth.key.data;
1156 : 0 : auth_key_len = auth_xform->auth.key.length;
1157 : :
1158 [ # # # # ]: 0 : switch (auth_xform->auth.algo) {
1159 : : case RTE_CRYPTO_AUTH_NULL:
1160 : : break;
1161 : 0 : case RTE_CRYPTO_AUTH_MD5_HMAC:
1162 : : case RTE_CRYPTO_AUTH_SHA1_HMAC:
1163 : 0 : memcpy(in_sa->sha1_or_gcm.hmac_key, auth_key,
1164 : : auth_key_len);
1165 : : ctx_len = offsetof(struct roc_ie_on_inb_sa,
1166 : : sha1_or_gcm.selector);
1167 : 0 : break;
1168 : 0 : case RTE_CRYPTO_AUTH_SHA256_HMAC:
1169 : : case RTE_CRYPTO_AUTH_SHA384_HMAC:
1170 : : case RTE_CRYPTO_AUTH_SHA512_HMAC:
1171 : 0 : memcpy(in_sa->sha2.hmac_key, auth_key, auth_key_len);
1172 : : ctx_len = offsetof(struct roc_ie_on_inb_sa,
1173 : : sha2.selector);
1174 : 0 : break;
1175 : 0 : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
1176 : 0 : memcpy(in_sa->aes_xcbc.key, auth_key, auth_key_len);
1177 : : ctx_len = offsetof(struct roc_ie_on_inb_sa,
1178 : : aes_xcbc.selector);
1179 : 0 : break;
1180 : 0 : default:
1181 : 0 : plt_err("Unsupported auth algorithm %u", auth_xform->auth.algo);
1182 : 0 : return -ENOTSUP;
1183 : : }
1184 [ # # ]: 0 : if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) {
1185 : 0 : const uint8_t *auth_key = auth_xform->auth.key.data;
1186 : :
1187 : 0 : roc_aes_xcbc_key_derive(auth_key, hmac_opad_ipad);
1188 [ # # ]: 0 : } else if (auth_xform->auth.algo != RTE_CRYPTO_AUTH_NULL) {
1189 : 0 : roc_se_hmac_opad_ipad_gen(
1190 : 0 : in_sa->common_sa.ctl.auth_type, auth_xform->auth.key.data,
1191 : 0 : auth_xform->auth.key.length, &hmac_opad_ipad[0], ROC_SE_IPSEC);
1192 : : }
1193 : : }
1194 : :
1195 : 0 : return ctx_len;
1196 : : }
1197 : :
1198 : : static int
1199 : 0 : ow_ipsec_sa_common_param_fill(union roc_ow_ipsec_sa_word2 *w2, uint8_t *cipher_key,
1200 : : uint8_t *salt_key, uint8_t *hmac_opad_ipad,
1201 : : struct rte_security_ipsec_xform *ipsec_xfrm,
1202 : : struct rte_crypto_sym_xform *crypto_xfrm)
1203 : : {
1204 : : struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm;
1205 : : const uint8_t *key = NULL;
1206 : : uint8_t ccm_flag = 0;
1207 : : uint32_t *tmp_salt;
1208 : : uint64_t *tmp_key;
1209 : : int i, length = 0;
1210 : :
1211 : : /* Set direction */
1212 [ # # ]: 0 : if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
1213 : 0 : w2->s.dir = ROC_IE_SA_DIR_OUTBOUND;
1214 : : else
1215 : 0 : w2->s.dir = ROC_IE_SA_DIR_INBOUND;
1216 : :
1217 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
1218 : : auth_xfrm = crypto_xfrm;
1219 : 0 : cipher_xfrm = crypto_xfrm->next;
1220 : : } else {
1221 : : cipher_xfrm = crypto_xfrm;
1222 : 0 : auth_xfrm = crypto_xfrm->next;
1223 : : }
1224 : :
1225 : : /* Set protocol - ESP vs AH */
1226 [ # # # ]: 0 : switch (ipsec_xfrm->proto) {
1227 : 0 : case RTE_SECURITY_IPSEC_SA_PROTO_ESP:
1228 : 0 : w2->s.protocol = ROC_IE_SA_PROTOCOL_ESP;
1229 : 0 : break;
1230 : 0 : case RTE_SECURITY_IPSEC_SA_PROTO_AH:
1231 : 0 : w2->s.protocol = ROC_IE_SA_PROTOCOL_AH;
1232 : 0 : break;
1233 : : default:
1234 : : return -EINVAL;
1235 : : }
1236 : :
1237 : : /* Set mode - transport vs tunnel */
1238 [ # # # ]: 0 : switch (ipsec_xfrm->mode) {
1239 : 0 : case RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT:
1240 : 0 : w2->s.mode = ROC_IE_SA_MODE_TRANSPORT;
1241 : 0 : break;
1242 : 0 : case RTE_SECURITY_IPSEC_SA_MODE_TUNNEL:
1243 : 0 : w2->s.mode = ROC_IE_SA_MODE_TUNNEL;
1244 : 0 : break;
1245 : : default:
1246 : : return -EINVAL;
1247 : : }
1248 : :
1249 : : /* Set encryption algorithm */
1250 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
1251 : 0 : key = crypto_xfrm->aead.key.data;
1252 : 0 : length = crypto_xfrm->aead.key.length;
1253 : :
1254 [ # # # ]: 0 : switch (crypto_xfrm->aead.algo) {
1255 : 0 : case RTE_CRYPTO_AEAD_AES_GCM:
1256 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_AES_GCM;
1257 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_NULL;
1258 [ # # ]: 0 : memcpy(salt_key, &ipsec_xfrm->salt, 4);
1259 : : tmp_salt = (uint32_t *)salt_key;
1260 [ # # ]: 0 : *tmp_salt = rte_be_to_cpu_32(*tmp_salt);
1261 : 0 : break;
1262 : 0 : case RTE_CRYPTO_AEAD_AES_CCM:
1263 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_AES_CCM;
1264 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_NULL;
1265 : : ccm_flag = 0x07 & ~ROC_CPT_AES_CCM_CTR_LEN;
1266 : 0 : *salt_key = ccm_flag;
1267 [ # # ]: 0 : memcpy(PLT_PTR_ADD(salt_key, 1), &ipsec_xfrm->salt, 3);
1268 : : tmp_salt = (uint32_t *)salt_key;
1269 [ # # ]: 0 : *tmp_salt = rte_be_to_cpu_32(*tmp_salt);
1270 : 0 : break;
1271 : : default:
1272 : : return -ENOTSUP;
1273 : : }
1274 : : } else {
1275 [ # # ]: 0 : if (cipher_xfrm != NULL) {
1276 [ # # # # : 0 : switch (cipher_xfrm->cipher.algo) {
# ]
1277 : 0 : case RTE_CRYPTO_CIPHER_NULL:
1278 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_NULL;
1279 : 0 : break;
1280 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
1281 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_AES_CBC;
1282 : 0 : break;
1283 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
1284 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_AES_CTR;
1285 : 0 : break;
1286 : 0 : case RTE_CRYPTO_CIPHER_3DES_CBC:
1287 : 0 : w2->s.enc_type = ROC_IE_SA_ENC_3DES_CBC;
1288 : 0 : break;
1289 : : default:
1290 : : return -ENOTSUP;
1291 : : }
1292 : :
1293 : 0 : key = cipher_xfrm->cipher.key.data;
1294 : 0 : length = cipher_xfrm->cipher.key.length;
1295 : : }
1296 : :
1297 [ # # # # : 0 : switch (auth_xfrm->auth.algo) {
# # # # ]
1298 : 0 : case RTE_CRYPTO_AUTH_NULL:
1299 [ # # # # ]: 0 : if (w2->s.dir == ROC_IE_SA_DIR_INBOUND && ipsec_xfrm->replay_win_sz) {
1300 : 0 : plt_err("anti-replay can't be supported with integrity service disabled");
1301 : 0 : return -EINVAL;
1302 : : }
1303 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_NULL;
1304 : 0 : break;
1305 : 0 : case RTE_CRYPTO_AUTH_SHA1_HMAC:
1306 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_SHA1;
1307 : 0 : break;
1308 : 0 : case RTE_CRYPTO_AUTH_SHA256_HMAC:
1309 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_SHA2_256;
1310 : 0 : break;
1311 : 0 : case RTE_CRYPTO_AUTH_SHA384_HMAC:
1312 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_SHA2_384;
1313 : 0 : break;
1314 : 0 : case RTE_CRYPTO_AUTH_SHA512_HMAC:
1315 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_SHA2_512;
1316 : 0 : break;
1317 : 0 : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
1318 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_AES_XCBC_128;
1319 : 0 : break;
1320 : 0 : case RTE_CRYPTO_AUTH_AES_GMAC:
1321 : 0 : w2->s.auth_type = ROC_IE_SA_AUTH_AES_GMAC;
1322 : 0 : key = auth_xfrm->auth.key.data;
1323 : 0 : length = auth_xfrm->auth.key.length;
1324 [ # # ]: 0 : memcpy(salt_key, &ipsec_xfrm->salt, 4);
1325 : : tmp_salt = (uint32_t *)salt_key;
1326 [ # # ]: 0 : *tmp_salt = rte_be_to_cpu_32(*tmp_salt);
1327 : 0 : break;
1328 : : default:
1329 : : return -ENOTSUP;
1330 : : }
1331 : :
1332 [ # # ]: 0 : if (auth_xfrm->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) {
1333 : 0 : const uint8_t *auth_key = auth_xfrm->auth.key.data;
1334 : 0 : roc_aes_xcbc_key_derive(auth_key, hmac_opad_ipad);
1335 : : } else {
1336 : 0 : roc_se_hmac_opad_ipad_gen(w2->s.auth_type, auth_xfrm->auth.key.data,
1337 : 0 : auth_xfrm->auth.key.length, &hmac_opad_ipad[0],
1338 : : ROC_SE_IPSEC);
1339 : : }
1340 : :
1341 : : tmp_key = (uint64_t *)hmac_opad_ipad;
1342 [ # # ]: 0 : for (i = 0; i < (int)(ROC_CTX_MAX_OPAD_IPAD_LEN / sizeof(uint64_t)); i++)
1343 [ # # ]: 0 : tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
1344 : : }
1345 : :
1346 : : /* Set encapsulation type */
1347 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap)
1348 : 0 : w2->s.encap_type = ROC_IE_OT_SA_ENCAP_UDP;
1349 : :
1350 : 0 : w2->s.spi = ipsec_xfrm->spi;
1351 : :
1352 [ # # ]: 0 : if (key != NULL && length != 0) {
1353 : : /* Copy encryption key */
1354 : 0 : memcpy(cipher_key, key, length);
1355 : : tmp_key = (uint64_t *)cipher_key;
1356 [ # # ]: 0 : for (i = 0; i < (int)(ROC_CTX_MAX_CKEY_LEN / sizeof(uint64_t)); i++)
1357 [ # # ]: 0 : tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
1358 : : }
1359 : :
1360 : : /* Set AES key length */
1361 [ # # # # ]: 0 : if (w2->s.enc_type == ROC_IE_SA_ENC_AES_CBC || w2->s.enc_type == ROC_IE_SA_ENC_AES_CCM ||
1362 [ # # ]: 0 : w2->s.enc_type == ROC_IE_SA_ENC_AES_CTR || w2->s.enc_type == ROC_IE_SA_ENC_AES_GCM ||
1363 [ # # ]: 0 : w2->s.enc_type == ROC_IE_SA_ENC_AES_CCM || w2->s.auth_type == ROC_IE_SA_AUTH_AES_GMAC) {
1364 [ # # # # ]: 0 : switch (length) {
1365 : 0 : case ROC_CPT_AES128_KEY_LEN:
1366 : 0 : w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_128;
1367 : 0 : break;
1368 : 0 : case ROC_CPT_AES192_KEY_LEN:
1369 : 0 : w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_192;
1370 : 0 : break;
1371 : 0 : case ROC_CPT_AES256_KEY_LEN:
1372 : 0 : w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_256;
1373 : 0 : break;
1374 : 0 : default:
1375 : 0 : plt_err("Invalid AES key length");
1376 : 0 : return -EINVAL;
1377 : : }
1378 : : }
1379 : :
1380 [ # # # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit != 0 || ipsec_xfrm->life.packets_hard_limit != 0) {
1381 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
1382 [ # # ]: 0 : ipsec_xfrm->life.bytes_hard_limit != 0) {
1383 : 0 : plt_err("Expiry tracking with both packets & bytes is not supported");
1384 : 0 : return -EINVAL;
1385 : : }
1386 : 0 : w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_PKTS;
1387 : : }
1388 : :
1389 [ # # # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit != 0 || ipsec_xfrm->life.bytes_hard_limit != 0) {
1390 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit != 0 ||
1391 [ # # ]: 0 : ipsec_xfrm->life.packets_hard_limit != 0) {
1392 : 0 : plt_err("Expiry tracking with both packets & bytes is not supported");
1393 : 0 : return -EINVAL;
1394 : : }
1395 : 0 : w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_OCTETS;
1396 : : }
1397 : :
1398 : : return 0;
1399 : : }
1400 : :
1401 : : static size_t
1402 : : ow_ipsec_inb_ctx_size(struct roc_ow_ipsec_inb_sa *sa)
1403 : : {
1404 : : size_t size;
1405 : :
1406 : : /* Variable based on Anti-replay Window */
1407 : : size = offsetof(struct roc_ow_ipsec_inb_sa, ctx) +
1408 : : offsetof(struct roc_ow_ipsec_inb_ctx_update_reg, ar_winbits);
1409 : :
1410 : 0 : if (sa->w0.s.ar_win)
1411 : 0 : size += (1 << (sa->w0.s.ar_win - 1)) * sizeof(uint64_t);
1412 : :
1413 : : return size;
1414 : : }
1415 : :
1416 : : static void
1417 : 0 : ow_ipsec_update_ipv6_addr_endianness(uint64_t *addr)
1418 : : {
1419 [ # # ]: 0 : *addr = rte_be_to_cpu_64(*addr);
1420 : : addr++;
1421 [ # # ]: 0 : *addr = rte_be_to_cpu_64(*addr);
1422 : 0 : }
1423 : :
1424 : : static int
1425 : 0 : ow_ipsec_inb_tunnel_hdr_fill(struct roc_ow_ipsec_inb_sa *sa,
1426 : : struct rte_security_ipsec_xform *ipsec_xfrm)
1427 : : {
1428 : : struct rte_security_ipsec_tunnel_param *tunnel;
1429 : :
1430 [ # # ]: 0 : if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
1431 : : return 0;
1432 : :
1433 [ # # ]: 0 : if (ipsec_xfrm->options.tunnel_hdr_verify == 0)
1434 : : return 0;
1435 : :
1436 : : tunnel = &ipsec_xfrm->tunnel;
1437 : :
1438 [ # # # ]: 0 : switch (tunnel->type) {
1439 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV4:
1440 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
1441 [ # # ]: 0 : memcpy(&sa->outer_hdr.ipv4.src_addr, &tunnel->ipv4.src_ip, sizeof(struct in_addr));
1442 : 0 : memcpy(&sa->outer_hdr.ipv4.dst_addr, &tunnel->ipv4.dst_ip, sizeof(struct in_addr));
1443 : :
1444 : : /* IP Source and Dest are in LE/CPU endian */
1445 [ # # ]: 0 : sa->outer_hdr.ipv4.src_addr = rte_be_to_cpu_32(sa->outer_hdr.ipv4.src_addr);
1446 [ # # ]: 0 : sa->outer_hdr.ipv4.dst_addr = rte_be_to_cpu_32(sa->outer_hdr.ipv4.dst_addr);
1447 : :
1448 : 0 : break;
1449 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV6:
1450 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
1451 : 0 : memcpy(&sa->outer_hdr.ipv6.src_addr, &tunnel->ipv6.src_addr,
1452 : : sizeof(struct in6_addr));
1453 : 0 : memcpy(&sa->outer_hdr.ipv6.dst_addr, &tunnel->ipv6.dst_addr,
1454 : : sizeof(struct in6_addr));
1455 : :
1456 : : /* IP Source and Dest are in LE/CPU endian */
1457 : 0 : ow_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.src_addr);
1458 : 0 : ow_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.dst_addr);
1459 : :
1460 : 0 : break;
1461 : : default:
1462 : : return -EINVAL;
1463 : : }
1464 : :
1465 [ # # # ]: 0 : switch (ipsec_xfrm->options.tunnel_hdr_verify) {
1466 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR:
1467 : 0 : sa->w2.s.ip_hdr_verify = ROC_IE_OT_SA_IP_HDR_VERIFY_DST_ADDR;
1468 : 0 : break;
1469 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR:
1470 : 0 : sa->w2.s.ip_hdr_verify = ROC_IE_OT_SA_IP_HDR_VERIFY_SRC_DST_ADDR;
1471 : 0 : break;
1472 : : default:
1473 : : return -ENOTSUP;
1474 : : }
1475 : :
1476 : : return 0;
1477 : : }
1478 : :
1479 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ow_ipsec_inb_sa_fill)
1480 : : int
1481 : 0 : cnxk_ow_ipsec_inb_sa_fill(struct roc_ow_ipsec_inb_sa *sa,
1482 : : struct rte_security_ipsec_xform *ipsec_xfrm,
1483 : : struct rte_crypto_sym_xform *crypto_xfrm)
1484 : : {
1485 : : uint16_t sport = 4500, dport = 4500;
1486 : : union roc_ow_ipsec_sa_word2 w2;
1487 : : uint32_t replay_win_sz;
1488 : : size_t offset;
1489 : : int rc;
1490 : :
1491 : : /* Initialize the SA */
1492 : 0 : roc_ow_ipsec_inb_sa_init(sa);
1493 : :
1494 : 0 : w2.u64 = 0;
1495 : 0 : rc = ow_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->w8.s.salt, sa->hmac_opad_ipad,
1496 : : ipsec_xfrm, crypto_xfrm);
1497 [ # # ]: 0 : if (rc)
1498 : : return rc;
1499 : :
1500 : : /* Updata common word2 data */
1501 : 0 : sa->w2.u64 = w2.u64;
1502 : :
1503 : : /* Only support power-of-two window sizes supported */
1504 : 0 : replay_win_sz = ipsec_xfrm->replay_win_sz;
1505 [ # # ]: 0 : if (replay_win_sz) {
1506 [ # # ]: 0 : if (!rte_is_power_of_2(replay_win_sz) || replay_win_sz > ROC_AR_WIN_SIZE_MAX)
1507 : : return -ENOTSUP;
1508 : :
1509 : 0 : sa->w0.s.ar_win = rte_log2_u32(replay_win_sz) - 5;
1510 : : }
1511 : :
1512 : 0 : rc = ow_ipsec_inb_tunnel_hdr_fill(sa, ipsec_xfrm);
1513 [ # # ]: 0 : if (rc)
1514 : : return rc;
1515 : :
1516 : : /* Default options for pkt_out and pkt_fmt are with
1517 : : * second pass meta and no defrag.
1518 : : */
1519 : 0 : sa->w0.s.pkt_format = ROC_IE_OT_SA_PKT_FMT_META;
1520 : 0 : sa->w0.s.pkt_output = ROC_IE_OT_SA_PKT_OUTPUT_NO_FRAG;
1521 : 0 : sa->w0.s.pkind = ROC_IE_OT_CPT_PKIND;
1522 : :
1523 [ # # ]: 0 : if (ipsec_xfrm->options.ip_reassembly_en)
1524 : 0 : sa->w0.s.pkt_output = ROC_IE_OT_SA_PKT_OUTPUT_HW_BASED_DEFRAG;
1525 : :
1526 : : /* ESN */
1527 : 0 : sa->w2.s.esn_en = !!ipsec_xfrm->options.esn;
1528 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap) {
1529 [ # # ]: 0 : if (ipsec_xfrm->udp.sport)
1530 : : sport = ipsec_xfrm->udp.sport;
1531 : :
1532 [ # # ]: 0 : if (ipsec_xfrm->udp.dport)
1533 : : dport = ipsec_xfrm->udp.dport;
1534 : :
1535 : 0 : sa->w10.s.udp_src_port = sport;
1536 : 0 : sa->w10.s.udp_dst_port = dport;
1537 : : }
1538 : :
1539 [ # # ]: 0 : if (ipsec_xfrm->options.udp_ports_verify)
1540 : 0 : sa->w2.s.udp_ports_verify = 1;
1541 : :
1542 : : offset = offsetof(struct roc_ow_ipsec_inb_sa, ctx);
1543 : : /* Word offset for HW managed SA field */
1544 : 0 : sa->w0.s.hw_ctx_off = offset / 8;
1545 : : /* Context push size for inbound spans up to hw_ctx including
1546 : : * ar_base field, in 8b units
1547 : : */
1548 [ # # ]: 0 : sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off + 1;
1549 : : /* Entire context size in 128B units */
1550 : 0 : sa->w0.s.ctx_size =
1551 : 0 : (PLT_ALIGN_CEIL(ow_ipsec_inb_ctx_size(sa), ROC_CTX_UNIT_128B) / ROC_CTX_UNIT_128B) -
1552 : : 1;
1553 : :
1554 : : /**
1555 : : * CPT MC triggers expiry when counter value changes from 2 to 1. To
1556 : : * mitigate this behaviour add 1 to the life counter values provided.
1557 : : */
1558 : :
1559 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit) {
1560 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
1561 : 0 : sa->w0.s.soft_life_dec = 1;
1562 : : }
1563 : :
1564 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit) {
1565 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
1566 : 0 : sa->w0.s.soft_life_dec = 1;
1567 : : }
1568 : :
1569 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_hard_limit) {
1570 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
1571 : 0 : sa->w0.s.hard_life_dec = 1;
1572 : : }
1573 : :
1574 [ # # ]: 0 : if (ipsec_xfrm->life.packets_hard_limit) {
1575 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
1576 : 0 : sa->w0.s.hard_life_dec = 1;
1577 : : }
1578 : :
1579 : : rte_wmb();
1580 : :
1581 : : /* Enable SA */
1582 : 0 : sa->w2.s.valid = 1;
1583 : 0 : return 0;
1584 : : }
1585 : :
1586 : : RTE_EXPORT_INTERNAL_SYMBOL(cnxk_ow_ipsec_outb_sa_fill)
1587 : : int
1588 : 0 : cnxk_ow_ipsec_outb_sa_fill(struct roc_ow_ipsec_outb_sa *sa,
1589 : : struct rte_security_ipsec_xform *ipsec_xfrm,
1590 : : struct rte_crypto_sym_xform *crypto_xfrm)
1591 : : {
1592 : : struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel;
1593 : : uint16_t sport = 4500, dport = 4500;
1594 : : union roc_ow_ipsec_sa_word2 w2;
1595 : : size_t offset;
1596 : : int rc;
1597 : :
1598 : : /* Initialize the SA */
1599 : 0 : roc_ow_ipsec_outb_sa_init(sa);
1600 : :
1601 : 0 : w2.u64 = 0;
1602 : 0 : rc = ow_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->iv.s.salt, sa->hmac_opad_ipad,
1603 : : ipsec_xfrm, crypto_xfrm);
1604 [ # # ]: 0 : if (rc)
1605 : : return rc;
1606 : :
1607 : : /* Update common word2 data */
1608 : 0 : sa->w2.u64 = w2.u64;
1609 : :
1610 [ # # ]: 0 : if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
1611 : 0 : goto skip_tunnel_info;
1612 : :
1613 : : /* Tunnel header info */
1614 [ # # # ]: 0 : switch (tunnel->type) {
1615 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV4:
1616 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
1617 [ # # ]: 0 : memcpy(&sa->outer_hdr.ipv4.src_addr, &tunnel->ipv4.src_ip, sizeof(struct in_addr));
1618 : 0 : memcpy(&sa->outer_hdr.ipv4.dst_addr, &tunnel->ipv4.dst_ip, sizeof(struct in_addr));
1619 : :
1620 : : /* IP Source and Dest seems to be in LE/CPU endian */
1621 [ # # ]: 0 : sa->outer_hdr.ipv4.src_addr = rte_be_to_cpu_32(sa->outer_hdr.ipv4.src_addr);
1622 [ # # ]: 0 : sa->outer_hdr.ipv4.dst_addr = rte_be_to_cpu_32(sa->outer_hdr.ipv4.dst_addr);
1623 : :
1624 : : /* Outer header DF bit source */
1625 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_df) {
1626 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src = ROC_IE_OT_SA_COPY_FROM_SA;
1627 : 0 : sa->w10.s.ipv4_df_or_ipv6_flw_lbl = tunnel->ipv4.df;
1628 : : } else {
1629 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
1630 : : ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
1631 : : }
1632 : :
1633 : : /* Outer header DSCP source */
1634 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_dscp) {
1635 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_SA;
1636 : 0 : sa->w10.s.dscp = tunnel->ipv4.dscp;
1637 : : } else {
1638 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
1639 : : }
1640 : : break;
1641 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV6:
1642 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
1643 : 0 : memcpy(&sa->outer_hdr.ipv6.src_addr, &tunnel->ipv6.src_addr,
1644 : : sizeof(struct in6_addr));
1645 : 0 : memcpy(&sa->outer_hdr.ipv6.dst_addr, &tunnel->ipv6.dst_addr,
1646 : : sizeof(struct in6_addr));
1647 : :
1648 : : /* IP Source and Dest are in LE/CPU endian */
1649 : 0 : ow_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.src_addr);
1650 : 0 : ow_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.dst_addr);
1651 : :
1652 : : /* Outer header flow label source */
1653 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_flabel) {
1654 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src = ROC_IE_OT_SA_COPY_FROM_SA;
1655 : :
1656 : 0 : sa->w10.s.ipv4_df_or_ipv6_flw_lbl = tunnel->ipv6.flabel;
1657 : : } else {
1658 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
1659 : : ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
1660 : : }
1661 : :
1662 : : /* Outer header DSCP source */
1663 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_dscp) {
1664 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_SA;
1665 : 0 : sa->w10.s.dscp = tunnel->ipv6.dscp;
1666 : : } else {
1667 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
1668 : : }
1669 : : break;
1670 : : default:
1671 : : return -EINVAL;
1672 : : }
1673 : :
1674 : 0 : skip_tunnel_info:
1675 : : /* ESN */
1676 : 0 : sa->w0.s.esn_en = !!ipsec_xfrm->options.esn;
1677 : :
1678 [ # # ]: 0 : if (ipsec_xfrm->esn.value)
1679 : 0 : sa->ctx.esn_val = ipsec_xfrm->esn.value - 1;
1680 : :
1681 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap) {
1682 [ # # ]: 0 : if (ipsec_xfrm->udp.sport)
1683 : : sport = ipsec_xfrm->udp.sport;
1684 : :
1685 [ # # ]: 0 : if (ipsec_xfrm->udp.dport)
1686 : : dport = ipsec_xfrm->udp.dport;
1687 : :
1688 : 0 : sa->w10.s.udp_src_port = sport;
1689 : 0 : sa->w10.s.udp_dst_port = dport;
1690 : : }
1691 : :
1692 : : offset = offsetof(struct roc_ow_ipsec_outb_sa, ctx);
1693 : : /* Word offset for HW managed SA field */
1694 : 0 : sa->w0.s.hw_ctx_off = offset / 8;
1695 : :
1696 : : /* Context push size is up to err ctl in HW ctx */
1697 : 0 : sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off + 1;
1698 : :
1699 : : /* Entire context size in 128B units */
1700 : : offset = sizeof(struct roc_ow_ipsec_outb_sa);
1701 : 0 : sa->w0.s.ctx_size = (PLT_ALIGN_CEIL(offset, ROC_CTX_UNIT_128B) / ROC_CTX_UNIT_128B) - 1;
1702 : :
1703 : : /* IPID gen */
1704 : 0 : sa->w2.s.ipid_gen = 1;
1705 : :
1706 : : /**
1707 : : * CPT MC triggers expiry when counter value changes from 2 to 1. To
1708 : : * mitigate this behaviour add 1 to the life counter values provided.
1709 : : */
1710 : :
1711 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit) {
1712 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
1713 : 0 : sa->w0.s.soft_life_dec = 1;
1714 : : }
1715 : :
1716 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit) {
1717 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
1718 : 0 : sa->w0.s.soft_life_dec = 1;
1719 : : }
1720 : :
1721 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_hard_limit) {
1722 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
1723 : 0 : sa->w0.s.hard_life_dec = 1;
1724 : : }
1725 : :
1726 [ # # ]: 0 : if (ipsec_xfrm->life.packets_hard_limit) {
1727 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
1728 : 0 : sa->w0.s.hard_life_dec = 1;
1729 : : }
1730 : :
1731 : : /* There are two words of CPT_CTX_HW_S for ucode to skip */
1732 : 0 : sa->w0.s.ctx_hdr_size = 1;
1733 : 0 : sa->w0.s.aop_valid = 1;
1734 : :
1735 : : rte_wmb();
1736 : :
1737 : : /* Enable SA */
1738 : 0 : sa->w2.s.valid = 1;
1739 : 0 : return 0;
1740 : : }
|