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 "cnxk_security.h"
8 : :
9 : : #include "roc_api.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_OT_SA_ENC_AES_GCM;
70 : 0 : w2->s.auth_type = ROC_IE_OT_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_OT_SA_ENC_AES_CCM;
77 : 0 : w2->s.auth_type = ROC_IE_OT_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_OT_SA_ENC_NULL;
92 : 0 : break;
93 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
94 : 0 : w2->s.enc_type = ROC_IE_OT_SA_ENC_AES_CBC;
95 : 0 : break;
96 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
97 : 0 : w2->s.enc_type = ROC_IE_OT_SA_ENC_AES_CTR;
98 : 0 : break;
99 : 0 : case RTE_CRYPTO_CIPHER_3DES_CBC:
100 : 0 : w2->s.enc_type = ROC_IE_OT_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_OT_SA_AUTH_NULL;
117 : 0 : break;
118 : 0 : case RTE_CRYPTO_AUTH_SHA1_HMAC:
119 : 0 : w2->s.auth_type = ROC_IE_OT_SA_AUTH_SHA1;
120 : 0 : break;
121 : 0 : case RTE_CRYPTO_AUTH_SHA256_HMAC:
122 : 0 : w2->s.auth_type = ROC_IE_OT_SA_AUTH_SHA2_256;
123 : 0 : break;
124 : 0 : case RTE_CRYPTO_AUTH_SHA384_HMAC:
125 : 0 : w2->s.auth_type = ROC_IE_OT_SA_AUTH_SHA2_384;
126 : 0 : break;
127 : 0 : case RTE_CRYPTO_AUTH_SHA512_HMAC:
128 : 0 : w2->s.auth_type = ROC_IE_OT_SA_AUTH_SHA2_512;
129 : 0 : break;
130 : 0 : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
131 : 0 : w2->s.auth_type = ROC_IE_OT_SA_AUTH_AES_XCBC_128;
132 : 0 : break;
133 : 0 : case RTE_CRYPTO_AUTH_AES_GMAC:
134 : 0 : w2->s.auth_type = ROC_IE_OT_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_OT_SA_ENC_AES_CBC ||
178 [ # # ]: 0 : w2->s.enc_type == ROC_IE_OT_SA_ENC_AES_CCM ||
179 [ # # ]: 0 : w2->s.enc_type == ROC_IE_OT_SA_ENC_AES_CTR ||
180 : : w2->s.enc_type == ROC_IE_OT_SA_ENC_AES_GCM ||
181 : 0 : w2->s.enc_type == ROC_IE_OT_SA_ENC_AES_CCM ||
182 [ # # ]: 0 : w2->s.auth_type == ROC_IE_OT_SA_AUTH_AES_GMAC) {
183 [ # # # # ]: 0 : switch (length) {
184 : 0 : case ROC_CPT_AES128_KEY_LEN:
185 : 0 : w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_128;
186 : 0 : break;
187 : 0 : case ROC_CPT_AES192_KEY_LEN:
188 : 0 : w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_192;
189 : 0 : break;
190 : 0 : case ROC_CPT_AES256_KEY_LEN:
191 : 0 : w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_256;
192 : 0 : break;
193 : 0 : default:
194 : 0 : plt_err("Invalid AES key length");
195 : 0 : return -EINVAL;
196 : : }
197 : : }
198 : :
199 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit != 0 ||
200 [ # # ]: 0 : ipsec_xfrm->life.packets_hard_limit != 0) {
201 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
202 [ # # ]: 0 : ipsec_xfrm->life.bytes_hard_limit != 0) {
203 : 0 : plt_err("Expiry tracking with both packets & bytes is not supported");
204 : 0 : return -EINVAL;
205 : : }
206 : 0 : w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_PKTS;
207 : : }
208 : :
209 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
210 [ # # ]: 0 : ipsec_xfrm->life.bytes_hard_limit != 0) {
211 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit != 0 ||
212 [ # # ]: 0 : ipsec_xfrm->life.packets_hard_limit != 0) {
213 : 0 : plt_err("Expiry tracking with both packets & bytes is not supported");
214 : 0 : return -EINVAL;
215 : : }
216 : 0 : w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_OCTETS;
217 : : }
218 : :
219 : : return 0;
220 : : }
221 : :
222 : : static size_t
223 : : ot_ipsec_inb_ctx_size(struct roc_ot_ipsec_inb_sa *sa)
224 : : {
225 : : size_t size;
226 : :
227 : : /* Variable based on Anti-replay Window */
228 : : size = offsetof(struct roc_ot_ipsec_inb_sa, ctx) +
229 : : offsetof(struct roc_ot_ipsec_inb_ctx_update_reg, ar_winbits);
230 : :
231 : 0 : if (sa->w0.s.ar_win)
232 : 0 : size += (1 << (sa->w0.s.ar_win - 1)) * sizeof(uint64_t);
233 : :
234 : : return size;
235 : : }
236 : :
237 : : static void
238 : 0 : ot_ipsec_update_ipv6_addr_endianness(uint64_t *addr)
239 : : {
240 [ # # ]: 0 : *addr = rte_be_to_cpu_64(*addr);
241 : : addr++;
242 [ # # ]: 0 : *addr = rte_be_to_cpu_64(*addr);
243 : 0 : }
244 : :
245 : : static int
246 : 0 : ot_ipsec_inb_tunnel_hdr_fill(struct roc_ot_ipsec_inb_sa *sa,
247 : : struct rte_security_ipsec_xform *ipsec_xfrm)
248 : : {
249 : : struct rte_security_ipsec_tunnel_param *tunnel;
250 : :
251 [ # # ]: 0 : if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
252 : : return 0;
253 : :
254 [ # # ]: 0 : if (ipsec_xfrm->options.tunnel_hdr_verify == 0)
255 : : return 0;
256 : :
257 : : tunnel = &ipsec_xfrm->tunnel;
258 : :
259 [ # # # ]: 0 : switch (tunnel->type) {
260 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV4:
261 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
262 [ # # ]: 0 : memcpy(&sa->outer_hdr.ipv4.src_addr, &tunnel->ipv4.src_ip,
263 : : sizeof(struct in_addr));
264 : 0 : memcpy(&sa->outer_hdr.ipv4.dst_addr, &tunnel->ipv4.dst_ip,
265 : : sizeof(struct in_addr));
266 : :
267 : : /* IP Source and Dest are in LE/CPU endian */
268 : 0 : sa->outer_hdr.ipv4.src_addr =
269 [ # # ]: 0 : rte_be_to_cpu_32(sa->outer_hdr.ipv4.src_addr);
270 : 0 : sa->outer_hdr.ipv4.dst_addr =
271 [ # # ]: 0 : rte_be_to_cpu_32(sa->outer_hdr.ipv4.dst_addr);
272 : :
273 : 0 : break;
274 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV6:
275 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
276 : 0 : memcpy(&sa->outer_hdr.ipv6.src_addr, &tunnel->ipv6.src_addr,
277 : : sizeof(struct in6_addr));
278 : 0 : memcpy(&sa->outer_hdr.ipv6.dst_addr, &tunnel->ipv6.dst_addr,
279 : : sizeof(struct in6_addr));
280 : :
281 : : /* IP Source and Dest are in LE/CPU endian */
282 : 0 : ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.src_addr);
283 : 0 : ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.dst_addr);
284 : :
285 : 0 : break;
286 : : default:
287 : : return -EINVAL;
288 : : }
289 : :
290 [ # # # ]: 0 : switch (ipsec_xfrm->options.tunnel_hdr_verify) {
291 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR:
292 : 0 : sa->w2.s.ip_hdr_verify = ROC_IE_OT_SA_IP_HDR_VERIFY_DST_ADDR;
293 : 0 : break;
294 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR:
295 : 0 : sa->w2.s.ip_hdr_verify =
296 : : ROC_IE_OT_SA_IP_HDR_VERIFY_SRC_DST_ADDR;
297 : 0 : break;
298 : : default:
299 : : return -ENOTSUP;
300 : : }
301 : :
302 : : return 0;
303 : : }
304 : :
305 : : int
306 : 0 : cnxk_ot_ipsec_inb_sa_fill(struct roc_ot_ipsec_inb_sa *sa,
307 : : struct rte_security_ipsec_xform *ipsec_xfrm,
308 : : struct rte_crypto_sym_xform *crypto_xfrm,
309 : : bool is_inline)
310 : : {
311 : : union roc_ot_ipsec_sa_word2 w2;
312 : : uint32_t replay_win_sz;
313 : : size_t offset;
314 : : int rc;
315 : :
316 : : /* Initialize the SA */
317 : 0 : roc_ot_ipsec_inb_sa_init(sa, is_inline);
318 : :
319 : 0 : w2.u64 = 0;
320 : 0 : rc = ot_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->w8.s.salt,
321 : 0 : sa->hmac_opad_ipad, ipsec_xfrm,
322 : : crypto_xfrm);
323 [ # # ]: 0 : if (rc)
324 : : return rc;
325 : :
326 : : /* Updata common word2 data */
327 : 0 : sa->w2.u64 = w2.u64;
328 : :
329 : : /* Only support power-of-two window sizes supported */
330 : 0 : replay_win_sz = ipsec_xfrm->replay_win_sz;
331 [ # # ]: 0 : if (replay_win_sz) {
332 [ # # ]: 0 : if (!rte_is_power_of_2(replay_win_sz) ||
333 : : replay_win_sz > ROC_AR_WIN_SIZE_MAX)
334 : : return -ENOTSUP;
335 : :
336 : 0 : sa->w0.s.ar_win = rte_log2_u32(replay_win_sz) - 5;
337 : : }
338 : :
339 : 0 : rc = ot_ipsec_inb_tunnel_hdr_fill(sa, ipsec_xfrm);
340 [ # # ]: 0 : if (rc)
341 : : return rc;
342 : :
343 : : /* Default options for pkt_out and pkt_fmt are with
344 : : * second pass meta and no defrag.
345 : : */
346 : 0 : sa->w0.s.pkt_format = ROC_IE_OT_SA_PKT_FMT_META;
347 : 0 : sa->w0.s.pkt_output = ROC_IE_OT_SA_PKT_OUTPUT_NO_FRAG;
348 : 0 : sa->w0.s.pkind = ROC_IE_OT_CPT_PKIND;
349 : :
350 [ # # ]: 0 : if (ipsec_xfrm->options.ip_reassembly_en)
351 : 0 : sa->w0.s.pkt_output = ROC_IE_OT_SA_PKT_OUTPUT_HW_BASED_DEFRAG;
352 : :
353 : : /* ESN */
354 : 0 : sa->w2.s.esn_en = !!ipsec_xfrm->options.esn;
355 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap) {
356 : 0 : sa->w10.s.udp_src_port = 4500;
357 : 0 : sa->w10.s.udp_dst_port = 4500;
358 : : }
359 : :
360 [ # # ]: 0 : if (ipsec_xfrm->options.udp_ports_verify)
361 : 0 : sa->w2.s.udp_ports_verify = 1;
362 : :
363 : : offset = offsetof(struct roc_ot_ipsec_inb_sa, ctx);
364 : : /* Word offset for HW managed SA field */
365 : 0 : sa->w0.s.hw_ctx_off = offset / 8;
366 : : /* Context push size for inbound spans up to hw_ctx including
367 : : * ar_base field, in 8b units
368 : : */
369 [ # # ]: 0 : sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off + 1;
370 : : /* Entire context size in 128B units */
371 : 0 : sa->w0.s.ctx_size =
372 : 0 : (PLT_ALIGN_CEIL(ot_ipsec_inb_ctx_size(sa), ROC_CTX_UNIT_128B) /
373 : 0 : ROC_CTX_UNIT_128B) -
374 : : 1;
375 : :
376 : : /**
377 : : * CPT MC triggers expiry when counter value changes from 2 to 1. To
378 : : * mitigate this behaviour add 1 to the life counter values provided.
379 : : */
380 : :
381 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit) {
382 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
383 : 0 : sa->w0.s.soft_life_dec = 1;
384 : : }
385 : :
386 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit) {
387 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
388 : 0 : sa->w0.s.soft_life_dec = 1;
389 : : }
390 : :
391 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_hard_limit) {
392 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
393 : 0 : sa->w0.s.hard_life_dec = 1;
394 : : }
395 : :
396 [ # # ]: 0 : if (ipsec_xfrm->life.packets_hard_limit) {
397 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
398 : 0 : sa->w0.s.hard_life_dec = 1;
399 : : }
400 : :
401 : : rte_wmb();
402 : :
403 : : /* Enable SA */
404 : 0 : sa->w2.s.valid = 1;
405 : 0 : return 0;
406 : : }
407 : :
408 : : int
409 : 0 : cnxk_ot_ipsec_outb_sa_fill(struct roc_ot_ipsec_outb_sa *sa,
410 : : struct rte_security_ipsec_xform *ipsec_xfrm,
411 : : struct rte_crypto_sym_xform *crypto_xfrm)
412 : : {
413 : : struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel;
414 : : union roc_ot_ipsec_sa_word2 w2;
415 : : size_t offset;
416 : : int rc;
417 : :
418 : : /* Initialize the SA */
419 : 0 : roc_ot_ipsec_outb_sa_init(sa);
420 : :
421 : 0 : w2.u64 = 0;
422 : 0 : rc = ot_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->iv.s.salt,
423 : 0 : sa->hmac_opad_ipad, ipsec_xfrm,
424 : : crypto_xfrm);
425 [ # # ]: 0 : if (rc)
426 : : return rc;
427 : :
428 : : /* Update common word2 data */
429 : 0 : sa->w2.u64 = w2.u64;
430 : :
431 [ # # ]: 0 : if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
432 : 0 : goto skip_tunnel_info;
433 : :
434 : : /* Tunnel header info */
435 [ # # # ]: 0 : switch (tunnel->type) {
436 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV4:
437 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
438 [ # # ]: 0 : memcpy(&sa->outer_hdr.ipv4.src_addr, &tunnel->ipv4.src_ip,
439 : : sizeof(struct in_addr));
440 : 0 : memcpy(&sa->outer_hdr.ipv4.dst_addr, &tunnel->ipv4.dst_ip,
441 : : sizeof(struct in_addr));
442 : :
443 : : /* IP Source and Dest seems to be in LE/CPU endian */
444 : 0 : sa->outer_hdr.ipv4.src_addr =
445 [ # # ]: 0 : rte_be_to_cpu_32(sa->outer_hdr.ipv4.src_addr);
446 : 0 : sa->outer_hdr.ipv4.dst_addr =
447 [ # # ]: 0 : rte_be_to_cpu_32(sa->outer_hdr.ipv4.dst_addr);
448 : :
449 : : /* Outer header DF bit source */
450 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_df) {
451 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
452 : : ROC_IE_OT_SA_COPY_FROM_SA;
453 : 0 : sa->w10.s.ipv4_df_or_ipv6_flw_lbl = tunnel->ipv4.df;
454 : : } else {
455 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
456 : : ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
457 : : }
458 : :
459 : : /* Outer header DSCP source */
460 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_dscp) {
461 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_SA;
462 : 0 : sa->w10.s.dscp = tunnel->ipv4.dscp;
463 : : } else {
464 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
465 : : }
466 : : break;
467 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV6:
468 : 0 : sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
469 : 0 : memcpy(&sa->outer_hdr.ipv6.src_addr, &tunnel->ipv6.src_addr,
470 : : sizeof(struct in6_addr));
471 : 0 : memcpy(&sa->outer_hdr.ipv6.dst_addr, &tunnel->ipv6.dst_addr,
472 : : sizeof(struct in6_addr));
473 : :
474 : : /* IP Source and Dest are in LE/CPU endian */
475 : 0 : ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.src_addr);
476 : 0 : ot_ipsec_update_ipv6_addr_endianness((uint64_t *)&sa->outer_hdr.ipv6.dst_addr);
477 : :
478 : : /* Outer header flow label source */
479 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_flabel) {
480 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
481 : : ROC_IE_OT_SA_COPY_FROM_SA;
482 : :
483 : 0 : sa->w10.s.ipv4_df_or_ipv6_flw_lbl = tunnel->ipv6.flabel;
484 : : } else {
485 : 0 : sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
486 : : ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
487 : : }
488 : :
489 : : /* Outer header DSCP source */
490 [ # # ]: 0 : if (!ipsec_xfrm->options.copy_dscp) {
491 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_SA;
492 : 0 : sa->w10.s.dscp = tunnel->ipv6.dscp;
493 : : } else {
494 : 0 : sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
495 : : }
496 : : break;
497 : : default:
498 : : return -EINVAL;
499 : : }
500 : :
501 : 0 : skip_tunnel_info:
502 : : /* ESN */
503 : 0 : sa->w0.s.esn_en = !!ipsec_xfrm->options.esn;
504 : :
505 [ # # ]: 0 : if (ipsec_xfrm->esn.value)
506 : 0 : sa->ctx.esn_val = ipsec_xfrm->esn.value - 1;
507 : :
508 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap) {
509 : 0 : sa->w10.s.udp_src_port = 4500;
510 : 0 : sa->w10.s.udp_dst_port = 4500;
511 : : }
512 : :
513 : : offset = offsetof(struct roc_ot_ipsec_outb_sa, ctx);
514 : : /* Word offset for HW managed SA field */
515 : 0 : sa->w0.s.hw_ctx_off = offset / 8;
516 : :
517 : : /* Context push size is up to err ctl in HW ctx */
518 : 0 : sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off + 1;
519 : :
520 : : /* Entire context size in 128B units */
521 : : offset = sizeof(struct roc_ot_ipsec_outb_sa);
522 : 0 : sa->w0.s.ctx_size = (PLT_ALIGN_CEIL(offset, ROC_CTX_UNIT_128B) /
523 : : ROC_CTX_UNIT_128B) -
524 : : 1;
525 : :
526 : : /* IPID gen */
527 : 0 : sa->w2.s.ipid_gen = 1;
528 : :
529 : : /**
530 : : * CPT MC triggers expiry when counter value changes from 2 to 1. To
531 : : * mitigate this behaviour add 1 to the life counter values provided.
532 : : */
533 : :
534 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_soft_limit) {
535 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
536 : 0 : sa->w0.s.soft_life_dec = 1;
537 : : }
538 : :
539 [ # # ]: 0 : if (ipsec_xfrm->life.packets_soft_limit) {
540 : 0 : sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
541 : 0 : sa->w0.s.soft_life_dec = 1;
542 : : }
543 : :
544 [ # # ]: 0 : if (ipsec_xfrm->life.bytes_hard_limit) {
545 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
546 : 0 : sa->w0.s.hard_life_dec = 1;
547 : : }
548 : :
549 [ # # ]: 0 : if (ipsec_xfrm->life.packets_hard_limit) {
550 : 0 : sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
551 : 0 : sa->w0.s.hard_life_dec = 1;
552 : : }
553 : :
554 : : /* There are two words of CPT_CTX_HW_S for ucode to skip */
555 : 0 : sa->w0.s.ctx_hdr_size = 1;
556 : 0 : sa->w0.s.aop_valid = 1;
557 : :
558 : : rte_wmb();
559 : :
560 : : /* Enable SA */
561 : 0 : sa->w2.s.valid = 1;
562 : 0 : return 0;
563 : : }
564 : :
565 : : bool
566 : 0 : cnxk_ot_ipsec_inb_sa_valid(struct roc_ot_ipsec_inb_sa *sa)
567 : : {
568 : 0 : return !!sa->w2.s.valid;
569 : : }
570 : :
571 : : bool
572 : 0 : cnxk_ot_ipsec_outb_sa_valid(struct roc_ot_ipsec_outb_sa *sa)
573 : : {
574 : 0 : return !!sa->w2.s.valid;
575 : : }
576 : :
577 : : static inline int
578 : : ipsec_xfrm_verify(struct rte_security_ipsec_xform *ipsec_xfrm,
579 : : struct rte_crypto_sym_xform *crypto_xfrm)
580 : : {
581 [ # # ]: 0 : if (crypto_xfrm->next == NULL)
582 : : return -EINVAL;
583 : :
584 [ # # ]: 0 : if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
585 [ # # ]: 0 : if (crypto_xfrm->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
586 [ # # ]: 0 : crypto_xfrm->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
587 : : return -EINVAL;
588 : : } else {
589 [ # # ]: 0 : if (crypto_xfrm->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
590 [ # # ]: 0 : crypto_xfrm->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
591 : : return -EINVAL;
592 : : }
593 : :
594 : : return 0;
595 : : }
596 : :
597 : : static int
598 : 0 : onf_ipsec_sa_common_param_fill(struct roc_ie_onf_sa_ctl *ctl, uint8_t *salt,
599 : : uint8_t *cipher_key, uint8_t *hmac_opad_ipad,
600 : : struct rte_security_ipsec_xform *ipsec_xfrm,
601 : : struct rte_crypto_sym_xform *crypto_xfrm)
602 : : {
603 : : struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm;
604 : : int rc, length, auth_key_len;
605 : : const uint8_t *key = NULL;
606 : : uint8_t ccm_flag = 0;
607 : :
608 : : /* Set direction */
609 [ # # # ]: 0 : switch (ipsec_xfrm->direction) {
610 : 0 : case RTE_SECURITY_IPSEC_SA_DIR_INGRESS:
611 : 0 : ctl->direction = ROC_IE_SA_DIR_INBOUND;
612 : : auth_xfrm = crypto_xfrm;
613 : 0 : cipher_xfrm = crypto_xfrm->next;
614 : 0 : break;
615 : 0 : case RTE_SECURITY_IPSEC_SA_DIR_EGRESS:
616 : 0 : ctl->direction = ROC_IE_SA_DIR_OUTBOUND;
617 : : cipher_xfrm = crypto_xfrm;
618 : 0 : auth_xfrm = crypto_xfrm->next;
619 : 0 : break;
620 : : default:
621 : : return -EINVAL;
622 : : }
623 : :
624 : : /* Set protocol - ESP vs AH */
625 [ # # # ]: 0 : switch (ipsec_xfrm->proto) {
626 : 0 : case RTE_SECURITY_IPSEC_SA_PROTO_ESP:
627 : 0 : ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP;
628 : : break;
629 : : case RTE_SECURITY_IPSEC_SA_PROTO_AH:
630 : : return -ENOTSUP;
631 : 0 : default:
632 : 0 : return -EINVAL;
633 : : }
634 : :
635 : : /* Set mode - transport vs tunnel */
636 [ # # # ]: 0 : switch (ipsec_xfrm->mode) {
637 : 0 : case RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT:
638 : 0 : ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT;
639 : 0 : break;
640 : 0 : case RTE_SECURITY_IPSEC_SA_MODE_TUNNEL:
641 : 0 : ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL;
642 : 0 : break;
643 : : default:
644 : : return -EINVAL;
645 : : }
646 : :
647 : : /* Set encryption algorithm */
648 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
649 : 0 : length = crypto_xfrm->aead.key.length;
650 : :
651 [ # # # ]: 0 : switch (crypto_xfrm->aead.algo) {
652 : 0 : case RTE_CRYPTO_AEAD_AES_GCM:
653 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_AES_GCM;
654 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL;
655 : 0 : memcpy(salt, &ipsec_xfrm->salt, 4);
656 : 0 : key = crypto_xfrm->aead.key.data;
657 : 0 : break;
658 : 0 : case RTE_CRYPTO_AEAD_AES_CCM:
659 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CCM;
660 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL;
661 : : ccm_flag = 0x07 & ~ROC_CPT_AES_CCM_CTR_LEN;
662 : 0 : *salt = ccm_flag;
663 : 0 : memcpy(PLT_PTR_ADD(salt, 1), &ipsec_xfrm->salt, 3);
664 : 0 : key = crypto_xfrm->aead.key.data;
665 : 0 : break;
666 : : default:
667 : : return -ENOTSUP;
668 : : }
669 : :
670 : : } else {
671 : : rc = ipsec_xfrm_verify(ipsec_xfrm, crypto_xfrm);
672 : : if (rc)
673 : : return rc;
674 : :
675 [ # # # ]: 0 : switch (cipher_xfrm->cipher.algo) {
676 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
677 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CBC;
678 : 0 : break;
679 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
680 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CTR;
681 : 0 : break;
682 : : default:
683 : : return -ENOTSUP;
684 : : }
685 : :
686 [ # # ]: 0 : switch (auth_xfrm->auth.algo) {
687 : 0 : case RTE_CRYPTO_AUTH_SHA1_HMAC:
688 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA1;
689 : : break;
690 : : default:
691 : : return -ENOTSUP;
692 : : }
693 : 0 : auth_key_len = auth_xfrm->auth.key.length;
694 [ # # ]: 0 : if (auth_key_len < 20 || auth_key_len > 64)
695 : : return -ENOTSUP;
696 : :
697 : 0 : key = cipher_xfrm->cipher.key.data;
698 : 0 : length = cipher_xfrm->cipher.key.length;
699 : :
700 : 0 : roc_se_hmac_opad_ipad_gen(ctl->auth_type, auth_xfrm->auth.key.data,
701 : : auth_xfrm->auth.key.length, hmac_opad_ipad, ROC_SE_IPSEC);
702 : : }
703 : :
704 [ # # # # ]: 0 : switch (length) {
705 : 0 : case ROC_CPT_AES128_KEY_LEN:
706 : 0 : ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128;
707 : 0 : break;
708 : 0 : case ROC_CPT_AES192_KEY_LEN:
709 : 0 : ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192;
710 : 0 : break;
711 : 0 : case ROC_CPT_AES256_KEY_LEN:
712 : 0 : ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256;
713 : 0 : break;
714 : : default:
715 : : return -EINVAL;
716 : : }
717 : :
718 [ # # ]: 0 : memcpy(cipher_key, key, length);
719 : :
720 [ # # ]: 0 : if (ipsec_xfrm->options.esn)
721 : 0 : ctl->esn_en = 1;
722 : :
723 [ # # ]: 0 : ctl->spi = rte_cpu_to_be_32(ipsec_xfrm->spi);
724 : 0 : return 0;
725 : : }
726 : :
727 : : int
728 : 0 : cnxk_onf_ipsec_inb_sa_fill(struct roc_onf_ipsec_inb_sa *sa,
729 : : struct rte_security_ipsec_xform *ipsec_xfrm,
730 : : struct rte_crypto_sym_xform *crypto_xfrm)
731 : : {
732 : 0 : struct roc_ie_onf_sa_ctl *ctl = &sa->ctl;
733 : : int rc;
734 : :
735 : 0 : rc = onf_ipsec_sa_common_param_fill(ctl, sa->nonce, sa->cipher_key,
736 : 0 : sa->hmac_key, ipsec_xfrm,
737 : : crypto_xfrm);
738 [ # # ]: 0 : if (rc)
739 : : return rc;
740 : :
741 : : rte_wmb();
742 : :
743 : : /* Enable SA */
744 : 0 : ctl->valid = 1;
745 : 0 : return 0;
746 : : }
747 : :
748 : : int
749 : 0 : cnxk_onf_ipsec_outb_sa_fill(struct roc_onf_ipsec_outb_sa *sa,
750 : : struct rte_security_ipsec_xform *ipsec_xfrm,
751 : : struct rte_crypto_sym_xform *crypto_xfrm)
752 : : {
753 : : struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel;
754 : 0 : struct roc_ie_onf_sa_ctl *ctl = &sa->ctl;
755 : : int rc;
756 : :
757 : : /* Fill common params */
758 : 0 : rc = onf_ipsec_sa_common_param_fill(ctl, sa->nonce, sa->cipher_key,
759 : 0 : sa->hmac_key, ipsec_xfrm,
760 : : crypto_xfrm);
761 [ # # ]: 0 : if (rc)
762 : : return rc;
763 : :
764 [ # # ]: 0 : if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
765 : 0 : goto skip_tunnel_info;
766 : :
767 : : /* Tunnel header info */
768 [ # # # ]: 0 : switch (tunnel->type) {
769 : 0 : case RTE_SECURITY_IPSEC_TUNNEL_IPV4:
770 [ # # ]: 0 : memcpy(&sa->ip_src, &tunnel->ipv4.src_ip,
771 : : sizeof(struct in_addr));
772 : 0 : memcpy(&sa->ip_dst, &tunnel->ipv4.dst_ip,
773 : : sizeof(struct in_addr));
774 : : break;
775 : : case RTE_SECURITY_IPSEC_TUNNEL_IPV6:
776 : : return -ENOTSUP;
777 : 0 : default:
778 : 0 : return -EINVAL;
779 : : }
780 : :
781 : : /* Update udp encap ports */
782 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap == 1) {
783 : 0 : sa->udp_src = 4500;
784 : 0 : sa->udp_dst = 4500;
785 : : }
786 : :
787 : 0 : skip_tunnel_info:
788 : : rte_wmb();
789 : :
790 : : /* Enable SA */
791 : 0 : ctl->valid = 1;
792 : 0 : return 0;
793 : : }
794 : :
795 : : bool
796 : 0 : cnxk_onf_ipsec_inb_sa_valid(struct roc_onf_ipsec_inb_sa *sa)
797 : : {
798 : 0 : return !!sa->ctl.valid;
799 : : }
800 : :
801 : : bool
802 : 0 : cnxk_onf_ipsec_outb_sa_valid(struct roc_onf_ipsec_outb_sa *sa)
803 : : {
804 : 0 : return !!sa->ctl.valid;
805 : : }
806 : :
807 : : uint8_t
808 : 0 : cnxk_ipsec_ivlen_get(enum rte_crypto_cipher_algorithm c_algo,
809 : : enum rte_crypto_auth_algorithm a_algo,
810 : : enum rte_crypto_aead_algorithm aead_algo)
811 : : {
812 : : uint8_t ivlen = 0;
813 : :
814 [ # # ]: 0 : if ((aead_algo == RTE_CRYPTO_AEAD_AES_GCM) || (aead_algo == RTE_CRYPTO_AEAD_AES_CCM))
815 : : ivlen = 8;
816 : :
817 [ # # # # ]: 0 : switch (c_algo) {
818 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
819 : : ivlen = 8;
820 : 0 : break;
821 : 0 : case RTE_CRYPTO_CIPHER_DES_CBC:
822 : : case RTE_CRYPTO_CIPHER_3DES_CBC:
823 : : ivlen = ROC_CPT_DES_BLOCK_LENGTH;
824 : 0 : break;
825 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
826 : : ivlen = ROC_CPT_AES_BLOCK_LENGTH;
827 : 0 : break;
828 : : default:
829 : : break;
830 : : }
831 : :
832 [ # # ]: 0 : switch (a_algo) {
833 : 0 : case RTE_CRYPTO_AUTH_AES_GMAC:
834 : : ivlen = 8;
835 : 0 : break;
836 : : default:
837 : : break;
838 : : }
839 : :
840 : 0 : return ivlen;
841 : : }
842 : :
843 : : uint8_t
844 [ # # ]: 0 : cnxk_ipsec_icvlen_get(enum rte_crypto_cipher_algorithm c_algo,
845 : : enum rte_crypto_auth_algorithm a_algo,
846 : : enum rte_crypto_aead_algorithm aead_algo)
847 : : {
848 : : uint8_t icv = 0;
849 : :
850 : : (void)c_algo;
851 : :
852 : : switch (a_algo) {
853 : : case RTE_CRYPTO_AUTH_NULL:
854 : : icv = 0;
855 : : break;
856 : : case RTE_CRYPTO_AUTH_MD5_HMAC:
857 : : case RTE_CRYPTO_AUTH_SHA1_HMAC:
858 : : icv = 12;
859 : : break;
860 : : case RTE_CRYPTO_AUTH_SHA256_HMAC:
861 : : case RTE_CRYPTO_AUTH_AES_GMAC:
862 : : icv = 16;
863 : : break;
864 : : case RTE_CRYPTO_AUTH_SHA384_HMAC:
865 : : icv = 24;
866 : : break;
867 : : case RTE_CRYPTO_AUTH_SHA512_HMAC:
868 : : icv = 32;
869 : : break;
870 : : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
871 : : icv = 12;
872 : : break;
873 : : default:
874 : : break;
875 : : }
876 : :
877 [ # # ]: 0 : switch (aead_algo) {
878 : 0 : case RTE_CRYPTO_AEAD_AES_GCM:
879 : : case RTE_CRYPTO_AEAD_AES_CCM:
880 : : icv = 16;
881 : 0 : break;
882 : : default:
883 : : break;
884 : : }
885 : :
886 : 0 : return icv;
887 : : }
888 : :
889 : : uint8_t
890 : 0 : cnxk_ipsec_outb_roundup_byte(enum rte_crypto_cipher_algorithm c_algo,
891 : : enum rte_crypto_aead_algorithm aead_algo)
892 : : {
893 : : uint8_t roundup_byte = 4;
894 : :
895 [ # # ]: 0 : if ((aead_algo == RTE_CRYPTO_AEAD_AES_GCM) || (aead_algo == RTE_CRYPTO_AEAD_AES_CCM))
896 : : return roundup_byte;
897 : :
898 [ # # # ]: 0 : switch (c_algo) {
899 : : case RTE_CRYPTO_CIPHER_AES_CTR:
900 : : roundup_byte = 4;
901 : : break;
902 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
903 : : roundup_byte = 16;
904 : 0 : break;
905 : 0 : case RTE_CRYPTO_CIPHER_DES_CBC:
906 : : case RTE_CRYPTO_CIPHER_3DES_CBC:
907 : : roundup_byte = 8;
908 : 0 : break;
909 : : case RTE_CRYPTO_CIPHER_NULL:
910 : : roundup_byte = 4;
911 : : break;
912 : : default:
913 : : break;
914 : : }
915 : :
916 : : return roundup_byte;
917 : : }
918 : :
919 : : int
920 [ # # ]: 0 : cnxk_ipsec_outb_rlens_get(struct cnxk_ipsec_outb_rlens *rlens,
921 : : struct rte_security_ipsec_xform *ipsec_xfrm,
922 : : struct rte_crypto_sym_xform *crypto_xfrm)
923 : : {
924 : : struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel;
925 : : enum rte_crypto_cipher_algorithm c_algo = RTE_CRYPTO_CIPHER_NULL;
926 : : enum rte_crypto_auth_algorithm a_algo = RTE_CRYPTO_AUTH_NULL;
927 : : enum rte_crypto_aead_algorithm aead_algo = 0;
928 : : uint16_t partial_len = 0;
929 : : uint8_t roundup_byte = 0;
930 : : int8_t roundup_len = 0;
931 : :
932 : : memset(rlens, 0, sizeof(struct cnxk_ipsec_outb_rlens));
933 : :
934 : : /* Get Cipher and Auth algo */
935 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
936 : 0 : aead_algo = crypto_xfrm->aead.algo;
937 : : } else {
938 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
939 : 0 : c_algo = crypto_xfrm->cipher.algo;
940 : : else
941 : 0 : a_algo = crypto_xfrm->auth.algo;
942 : :
943 [ # # ]: 0 : if (crypto_xfrm->next) {
944 [ # # ]: 0 : if (crypto_xfrm->next->type ==
945 : : RTE_CRYPTO_SYM_XFORM_CIPHER)
946 : 0 : c_algo = crypto_xfrm->next->cipher.algo;
947 : : else
948 : 0 : a_algo = crypto_xfrm->next->auth.algo;
949 : : }
950 : : }
951 : :
952 [ # # ]: 0 : if (ipsec_xfrm->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) {
953 : : partial_len = ROC_CPT_ESP_HDR_LEN;
954 : : roundup_len = ROC_CPT_ESP_TRL_LEN;
955 : : } else {
956 : : partial_len = ROC_CPT_AH_HDR_LEN;
957 : : }
958 : :
959 [ # # ]: 0 : if (ipsec_xfrm->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
960 [ # # ]: 0 : if (tunnel->type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
961 : 0 : partial_len += ROC_CPT_TUNNEL_IPV4_HDR_LEN;
962 : : else
963 : 0 : partial_len += ROC_CPT_TUNNEL_IPV6_HDR_LEN;
964 : : }
965 : :
966 : 0 : partial_len += cnxk_ipsec_ivlen_get(c_algo, a_algo, aead_algo);
967 : 0 : partial_len += cnxk_ipsec_icvlen_get(c_algo, a_algo, aead_algo);
968 : 0 : roundup_byte = cnxk_ipsec_outb_roundup_byte(c_algo, aead_algo);
969 : :
970 [ # # ]: 0 : if (ipsec_xfrm->options.udp_encap)
971 : 0 : partial_len += sizeof(struct rte_udp_hdr);
972 : :
973 : 0 : rlens->partial_len = partial_len;
974 : 0 : rlens->roundup_len = roundup_len;
975 : 0 : rlens->roundup_byte = roundup_byte;
976 : 0 : rlens->max_extended_len = partial_len + roundup_len + roundup_byte;
977 : 0 : return 0;
978 : : }
979 : :
980 : : static inline int
981 : 0 : on_ipsec_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
982 : : struct rte_crypto_sym_xform *crypto_xform,
983 : : struct roc_ie_on_sa_ctl *ctl)
984 : : {
985 : : struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
986 : : int aes_key_len = 0;
987 : :
988 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
989 : : auth_xform = crypto_xform;
990 : 0 : cipher_xform = crypto_xform->next;
991 : : } else {
992 : : cipher_xform = crypto_xform;
993 : 0 : auth_xform = crypto_xform->next;
994 : : }
995 : :
996 [ # # ]: 0 : if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS)
997 : 0 : ctl->direction = ROC_IE_SA_DIR_OUTBOUND;
998 : : else
999 : 0 : ctl->direction = ROC_IE_SA_DIR_INBOUND;
1000 : :
1001 [ # # ]: 0 : if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
1002 [ # # ]: 0 : if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
1003 : 0 : ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
1004 [ # # ]: 0 : else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
1005 : 0 : ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
1006 : : else
1007 : : return -EINVAL;
1008 : : }
1009 : :
1010 [ # # ]: 0 : if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) {
1011 : 0 : ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT;
1012 : 0 : ctl->outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
1013 [ # # ]: 0 : } else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
1014 : 0 : ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL;
1015 : : else
1016 : : return -EINVAL;
1017 : :
1018 [ # # ]: 0 : if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
1019 : 0 : ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_AH;
1020 [ # # ]: 0 : else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP)
1021 : 0 : ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP;
1022 : : else
1023 : : return -EINVAL;
1024 : :
1025 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
1026 [ # # # ]: 0 : switch (crypto_xform->aead.algo) {
1027 : 0 : case RTE_CRYPTO_AEAD_AES_GCM:
1028 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_AES_GCM;
1029 : 0 : aes_key_len = crypto_xform->aead.key.length;
1030 : 0 : break;
1031 : 0 : case RTE_CRYPTO_AEAD_AES_CCM:
1032 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CCM;
1033 : 0 : aes_key_len = crypto_xform->aead.key.length;
1034 : 0 : break;
1035 : 0 : default:
1036 : 0 : plt_err("Unsupported AEAD algorithm");
1037 : 0 : return -ENOTSUP;
1038 : : }
1039 : : } else {
1040 [ # # ]: 0 : if (cipher_xform != NULL) {
1041 [ # # # # : 0 : switch (cipher_xform->cipher.algo) {
# # ]
1042 : 0 : case RTE_CRYPTO_CIPHER_NULL:
1043 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_NULL;
1044 : 0 : break;
1045 : 0 : case RTE_CRYPTO_CIPHER_DES_CBC:
1046 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_DES_CBC;
1047 : 0 : break;
1048 : 0 : case RTE_CRYPTO_CIPHER_3DES_CBC:
1049 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_3DES_CBC;
1050 : 0 : break;
1051 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
1052 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CBC;
1053 : 0 : aes_key_len = cipher_xform->cipher.key.length;
1054 : 0 : break;
1055 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
1056 : 0 : ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CTR;
1057 : 0 : aes_key_len = cipher_xform->cipher.key.length;
1058 : 0 : break;
1059 : 0 : default:
1060 : 0 : plt_err("Unsupported cipher algorithm");
1061 : 0 : return -ENOTSUP;
1062 : : }
1063 : : }
1064 : :
1065 [ # # # # : 0 : switch (auth_xform->auth.algo) {
# # # # #
# ]
1066 : 0 : case RTE_CRYPTO_AUTH_NULL:
1067 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL;
1068 : 0 : break;
1069 : 0 : case RTE_CRYPTO_AUTH_MD5_HMAC:
1070 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_MD5;
1071 : 0 : break;
1072 : 0 : case RTE_CRYPTO_AUTH_SHA1_HMAC:
1073 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA1;
1074 : 0 : break;
1075 : 0 : case RTE_CRYPTO_AUTH_SHA224_HMAC:
1076 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_224;
1077 : 0 : break;
1078 : 0 : case RTE_CRYPTO_AUTH_SHA256_HMAC:
1079 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_256;
1080 : 0 : break;
1081 : 0 : case RTE_CRYPTO_AUTH_SHA384_HMAC:
1082 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_384;
1083 : 0 : break;
1084 : 0 : case RTE_CRYPTO_AUTH_SHA512_HMAC:
1085 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA2_512;
1086 : 0 : break;
1087 : 0 : case RTE_CRYPTO_AUTH_AES_GMAC:
1088 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_GMAC;
1089 : 0 : aes_key_len = auth_xform->auth.key.length;
1090 : 0 : break;
1091 : 0 : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
1092 : 0 : ctl->auth_type = ROC_IE_ON_SA_AUTH_AES_XCBC_128;
1093 : 0 : break;
1094 : 0 : default:
1095 : 0 : plt_err("Unsupported auth algorithm");
1096 : 0 : return -ENOTSUP;
1097 : : }
1098 : : }
1099 : :
1100 : : /* Set AES key length */
1101 [ # # ]: 0 : if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CBC ||
1102 [ # # ]: 0 : ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CCM ||
1103 [ # # ]: 0 : ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CTR ||
1104 : : ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM ||
1105 : 0 : ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CCM ||
1106 [ # # ]: 0 : ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) {
1107 [ # # # # ]: 0 : switch (aes_key_len) {
1108 : 0 : case 16:
1109 : 0 : ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128;
1110 : 0 : break;
1111 : 0 : case 24:
1112 : 0 : ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192;
1113 : 0 : break;
1114 : 0 : case 32:
1115 : 0 : ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256;
1116 : 0 : break;
1117 : 0 : default:
1118 : 0 : plt_err("Invalid AES key length");
1119 : 0 : return -EINVAL;
1120 : : }
1121 : : }
1122 : :
1123 [ # # ]: 0 : if (ipsec->options.esn)
1124 : 0 : ctl->esn_en = 1;
1125 : :
1126 [ # # ]: 0 : if (ipsec->options.udp_encap == 1)
1127 : 0 : ctl->encap_type = ROC_IE_ON_SA_ENCAP_UDP;
1128 : :
1129 : 0 : ctl->copy_df = ipsec->options.copy_df;
1130 : :
1131 [ # # ]: 0 : ctl->spi = rte_cpu_to_be_32(ipsec->spi);
1132 : :
1133 : 0 : rte_io_wmb();
1134 : :
1135 : 0 : ctl->valid = 1;
1136 : :
1137 : 0 : return 0;
1138 : : }
1139 : :
1140 : : static inline int
1141 : 0 : on_fill_ipsec_common_sa(struct rte_security_ipsec_xform *ipsec,
1142 : : struct rte_crypto_sym_xform *crypto_xform,
1143 : : struct roc_ie_on_common_sa *common_sa)
1144 : : {
1145 : : struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
1146 : : const uint8_t *cipher_key;
1147 : : int cipher_key_len = 0;
1148 : : uint8_t ccm_flag = 0;
1149 : : int ret;
1150 : :
1151 : 0 : ret = on_ipsec_sa_ctl_set(ipsec, crypto_xform, &common_sa->ctl);
1152 [ # # ]: 0 : if (ret)
1153 : : return ret;
1154 : :
1155 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
1156 : : auth_xform = crypto_xform;
1157 : 0 : cipher_xform = crypto_xform->next;
1158 : : } else {
1159 : : cipher_xform = crypto_xform;
1160 : 0 : auth_xform = crypto_xform->next;
1161 : : }
1162 : :
1163 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
1164 [ # # ]: 0 : if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM)
1165 : 0 : memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4);
1166 [ # # ]: 0 : else if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM) {
1167 : : ccm_flag = 0x07 & ~ROC_CPT_AES_CCM_CTR_LEN;
1168 : 0 : *common_sa->iv.gcm.nonce = ccm_flag;
1169 : 0 : memcpy(PLT_PTR_ADD(common_sa->iv.gcm.nonce, 1), &ipsec->salt, 3);
1170 : : }
1171 : 0 : cipher_key = crypto_xform->aead.key.data;
1172 : 0 : cipher_key_len = crypto_xform->aead.key.length;
1173 : : } else {
1174 [ # # ]: 0 : if (cipher_xform) {
1175 : 0 : cipher_key = cipher_xform->cipher.key.data;
1176 : 0 : cipher_key_len = cipher_xform->cipher.key.length;
1177 : : }
1178 : :
1179 [ # # ]: 0 : if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
1180 : 0 : memcpy(common_sa->iv.gcm.nonce, &ipsec->salt, 4);
1181 : 0 : cipher_key = auth_xform->auth.key.data;
1182 : 0 : cipher_key_len = auth_xform->auth.key.length;
1183 : : }
1184 : : }
1185 : :
1186 [ # # ]: 0 : if (cipher_key_len != 0)
1187 : 0 : memcpy(common_sa->cipher_key, cipher_key, cipher_key_len);
1188 : :
1189 : : return 0;
1190 : : }
1191 : :
1192 : : int
1193 : 0 : cnxk_on_ipsec_outb_sa_create(struct rte_security_ipsec_xform *ipsec,
1194 : : struct rte_crypto_sym_xform *crypto_xform,
1195 : : struct roc_ie_on_outb_sa *out_sa)
1196 : : {
1197 : : struct roc_ie_on_ip_template *template = NULL;
1198 : : struct rte_crypto_sym_xform *auth_xform;
1199 : : struct roc_ie_on_sa_ctl *ctl;
1200 : : struct rte_ipv6_hdr *ip6;
1201 : : struct rte_ipv4_hdr *ip4;
1202 : : uint16_t sport, dport;
1203 : : size_t ctx_len;
1204 : : int ret;
1205 : :
1206 : : ctl = &out_sa->common_sa.ctl;
1207 : :
1208 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH)
1209 : : auth_xform = crypto_xform;
1210 : : else
1211 : 0 : auth_xform = crypto_xform->next;
1212 : :
1213 : 0 : ret = on_fill_ipsec_common_sa(ipsec, crypto_xform, &out_sa->common_sa);
1214 [ # # ]: 0 : if (ret)
1215 : : return ret;
1216 : :
1217 [ # # ]: 0 : if (ctl->enc_type == ROC_IE_ON_SA_ENC_AES_GCM ||
1218 [ # # # # ]: 0 : ctl->enc_type == ROC_IE_ON_SA_ENC_AES_CCM || ctl->auth_type == ROC_IE_ON_SA_AUTH_NULL ||
1219 : : ctl->auth_type == ROC_IE_ON_SA_AUTH_AES_GMAC) {
1220 : 0 : template = &out_sa->aes_gcm.template;
1221 : 0 : ctx_len = offsetof(struct roc_ie_on_outb_sa, aes_gcm.template);
1222 : : } else {
1223 [ # # # # ]: 0 : switch (ctl->auth_type) {
1224 : 0 : case ROC_IE_ON_SA_AUTH_MD5:
1225 : : case ROC_IE_ON_SA_AUTH_SHA1:
1226 : 0 : template = &out_sa->sha1.template;
1227 : : ctx_len = offsetof(struct roc_ie_on_outb_sa,
1228 : : sha1.template);
1229 : 0 : break;
1230 : 0 : case ROC_IE_ON_SA_AUTH_SHA2_256:
1231 : : case ROC_IE_ON_SA_AUTH_SHA2_384:
1232 : : case ROC_IE_ON_SA_AUTH_SHA2_512:
1233 : 0 : template = &out_sa->sha2.template;
1234 : : ctx_len = offsetof(struct roc_ie_on_outb_sa,
1235 : : sha2.template);
1236 : 0 : break;
1237 : 0 : case ROC_IE_ON_SA_AUTH_AES_XCBC_128:
1238 : 0 : template = &out_sa->aes_xcbc.template;
1239 : : ctx_len = offsetof(struct roc_ie_on_outb_sa,
1240 : : aes_xcbc.template);
1241 : 0 : break;
1242 : 0 : default:
1243 : 0 : plt_err("Unsupported auth algorithm");
1244 : 0 : return -EINVAL;
1245 : : }
1246 : : }
1247 : :
1248 : : ip4 = (struct rte_ipv4_hdr *)&template->ip4.ipv4_hdr;
1249 : :
1250 : : sport = 4500;
1251 : : dport = 4500;
1252 : :
1253 : : /* If custom port values are provided, Overwrite default port values. */
1254 [ # # ]: 0 : if (ipsec->options.udp_encap) {
1255 : :
1256 [ # # ]: 0 : if (ipsec->udp.sport)
1257 : : sport = ipsec->udp.sport;
1258 : :
1259 [ # # ]: 0 : if (ipsec->udp.dport)
1260 : : dport = ipsec->udp.dport;
1261 : :
1262 : 0 : ip4->next_proto_id = IPPROTO_UDP;
1263 [ # # ]: 0 : template->ip4.udp_src = rte_be_to_cpu_16(sport);
1264 [ # # ]: 0 : template->ip4.udp_dst = rte_be_to_cpu_16(dport);
1265 : : } else {
1266 [ # # ]: 0 : if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
1267 : 0 : ip4->next_proto_id = IPPROTO_AH;
1268 : : else
1269 : 0 : ip4->next_proto_id = IPPROTO_ESP;
1270 : : }
1271 : :
1272 [ # # ]: 0 : if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
1273 [ # # ]: 0 : if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) {
1274 : : uint16_t frag_off = 0;
1275 : :
1276 : 0 : ctx_len += sizeof(template->ip4);
1277 : :
1278 : 0 : ip4->version_ihl = RTE_IPV4_VHL_DEF;
1279 [ # # ]: 0 : ip4->time_to_live = ipsec->tunnel.ipv4.ttl ?
1280 : : ipsec->tunnel.ipv4.ttl :
1281 : : 0x40;
1282 : 0 : ip4->type_of_service |= (ipsec->tunnel.ipv4.dscp << 2);
1283 [ # # ]: 0 : if (ipsec->tunnel.ipv4.df)
1284 : : frag_off |= RTE_IPV4_HDR_DF_FLAG;
1285 [ # # ]: 0 : ip4->fragment_offset = rte_cpu_to_be_16(frag_off);
1286 : :
1287 : 0 : memcpy(&ip4->src_addr, &ipsec->tunnel.ipv4.src_ip,
1288 : : sizeof(struct in_addr));
1289 : 0 : memcpy(&ip4->dst_addr, &ipsec->tunnel.ipv4.dst_ip,
1290 : : sizeof(struct in_addr));
1291 [ # # ]: 0 : } else if (ipsec->tunnel.type ==
1292 : : RTE_SECURITY_IPSEC_TUNNEL_IPV6) {
1293 : 0 : ctx_len += sizeof(template->ip6);
1294 : :
1295 : : ip6 = (struct rte_ipv6_hdr *)&template->ip6.ipv6_hdr;
1296 [ # # ]: 0 : if (ipsec->options.udp_encap) {
1297 : 0 : ip6->proto = IPPROTO_UDP;
1298 [ # # ]: 0 : template->ip6.udp_src = rte_be_to_cpu_16(sport);
1299 [ # # ]: 0 : template->ip6.udp_dst = rte_be_to_cpu_16(dport);
1300 : : } else {
1301 [ # # ]: 0 : ip6->proto = (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) ?
1302 : : IPPROTO_ESP :
1303 : : IPPROTO_AH;
1304 : : }
1305 : 0 : ip6->vtc_flow =
1306 [ # # ]: 0 : rte_cpu_to_be_32(0x60000000 |
1307 : : ((ipsec->tunnel.ipv6.dscp
1308 : : << RTE_IPV6_HDR_TC_SHIFT) &
1309 : : RTE_IPV6_HDR_TC_MASK) |
1310 : : ((ipsec->tunnel.ipv6.flabel
1311 : : << RTE_IPV6_HDR_FL_SHIFT) &
1312 : : RTE_IPV6_HDR_FL_MASK));
1313 [ # # ]: 0 : ip6->hop_limits = ipsec->tunnel.ipv6.hlimit ?
1314 : : ipsec->tunnel.ipv6.hlimit :
1315 : : 0x40;
1316 : 0 : memcpy(&ip6->src_addr, &ipsec->tunnel.ipv6.src_addr,
1317 : : sizeof(struct in6_addr));
1318 : 0 : memcpy(&ip6->dst_addr, &ipsec->tunnel.ipv6.dst_addr,
1319 : : sizeof(struct in6_addr));
1320 : : }
1321 : : } else
1322 : 0 : ctx_len += sizeof(template->ip4);
1323 : :
1324 : 0 : ctx_len = RTE_ALIGN_CEIL(ctx_len, 8);
1325 : :
1326 [ # # ]: 0 : if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
1327 : 0 : uint8_t *hmac_opad_ipad = (uint8_t *)&out_sa->sha2;
1328 : :
1329 [ # # ]: 0 : if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) {
1330 : 0 : const uint8_t *auth_key = auth_xform->auth.key.data;
1331 : :
1332 : 0 : roc_aes_xcbc_key_derive(auth_key, hmac_opad_ipad);
1333 [ # # ]: 0 : } else if (auth_xform->auth.algo != RTE_CRYPTO_AUTH_NULL) {
1334 : 0 : roc_se_hmac_opad_ipad_gen(
1335 : 0 : out_sa->common_sa.ctl.auth_type, auth_xform->auth.key.data,
1336 : 0 : auth_xform->auth.key.length, &hmac_opad_ipad[0], ROC_SE_IPSEC);
1337 : : }
1338 : : }
1339 : :
1340 : 0 : return ctx_len;
1341 : : }
1342 : :
1343 : : int
1344 : 0 : cnxk_on_ipsec_inb_sa_create(struct rte_security_ipsec_xform *ipsec,
1345 : : struct rte_crypto_sym_xform *crypto_xform,
1346 : : struct roc_ie_on_inb_sa *in_sa)
1347 : : {
1348 : : struct rte_crypto_sym_xform *auth_xform = crypto_xform;
1349 : : const uint8_t *auth_key;
1350 : : int auth_key_len = 0;
1351 : : size_t ctx_len = 0;
1352 : : int ret;
1353 : :
1354 : 0 : ret = on_fill_ipsec_common_sa(ipsec, crypto_xform, &in_sa->common_sa);
1355 [ # # ]: 0 : if (ret)
1356 : : return ret;
1357 : :
1358 [ # # ]: 0 : if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AEAD &&
1359 [ # # # # ]: 0 : crypto_xform->auth.algo == RTE_CRYPTO_AUTH_NULL && ipsec->replay_win_sz) {
1360 : 0 : plt_err("anti-replay can't be supported with integrity service disabled");
1361 : 0 : return -EINVAL;
1362 : : }
1363 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD ||
1364 [ # # # # ]: 0 : auth_xform->auth.algo == RTE_CRYPTO_AUTH_NULL ||
1365 : : auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
1366 : : ctx_len = offsetof(struct roc_ie_on_inb_sa, sha1_or_gcm.hmac_key[0]);
1367 : : } else {
1368 : 0 : uint8_t *hmac_opad_ipad = (uint8_t *)&in_sa->sha2;
1369 : 0 : auth_key = auth_xform->auth.key.data;
1370 : 0 : auth_key_len = auth_xform->auth.key.length;
1371 : :
1372 [ # # # # ]: 0 : switch (auth_xform->auth.algo) {
1373 : : case RTE_CRYPTO_AUTH_NULL:
1374 : : break;
1375 : 0 : case RTE_CRYPTO_AUTH_MD5_HMAC:
1376 : : case RTE_CRYPTO_AUTH_SHA1_HMAC:
1377 : 0 : memcpy(in_sa->sha1_or_gcm.hmac_key, auth_key,
1378 : : auth_key_len);
1379 : : ctx_len = offsetof(struct roc_ie_on_inb_sa,
1380 : : sha1_or_gcm.selector);
1381 : 0 : break;
1382 : 0 : case RTE_CRYPTO_AUTH_SHA256_HMAC:
1383 : : case RTE_CRYPTO_AUTH_SHA384_HMAC:
1384 : : case RTE_CRYPTO_AUTH_SHA512_HMAC:
1385 : 0 : memcpy(in_sa->sha2.hmac_key, auth_key, auth_key_len);
1386 : : ctx_len = offsetof(struct roc_ie_on_inb_sa,
1387 : : sha2.selector);
1388 : 0 : break;
1389 : 0 : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
1390 : 0 : memcpy(in_sa->aes_xcbc.key, auth_key, auth_key_len);
1391 : : ctx_len = offsetof(struct roc_ie_on_inb_sa,
1392 : : aes_xcbc.selector);
1393 : 0 : break;
1394 : 0 : default:
1395 : 0 : plt_err("Unsupported auth algorithm %u", auth_xform->auth.algo);
1396 : 0 : return -ENOTSUP;
1397 : : }
1398 [ # # ]: 0 : if (auth_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC) {
1399 : 0 : const uint8_t *auth_key = auth_xform->auth.key.data;
1400 : :
1401 : 0 : roc_aes_xcbc_key_derive(auth_key, hmac_opad_ipad);
1402 [ # # ]: 0 : } else if (auth_xform->auth.algo != RTE_CRYPTO_AUTH_NULL) {
1403 : 0 : roc_se_hmac_opad_ipad_gen(
1404 : 0 : in_sa->common_sa.ctl.auth_type, auth_xform->auth.key.data,
1405 : 0 : auth_xform->auth.key.length, &hmac_opad_ipad[0], ROC_SE_IPSEC);
1406 : : }
1407 : : }
1408 : :
1409 : 0 : return ctx_len;
1410 : : }
|