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