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