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