1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2021 Marvell.
7 #include "cnxk_security.h"
12 ipsec_hmac_opad_ipad_gen(struct rte_crypto_sym_xform *auth_xform,
13 uint8_t *hmac_opad_ipad)
15 const uint8_t *key = auth_xform->auth.key.data;
16 uint32_t length = auth_xform->auth.key.length;
17 uint8_t opad[128] = {[0 ... 127] = 0x5c};
18 uint8_t ipad[128] = {[0 ... 127] = 0x36};
21 /* HMAC OPAD and IPAD */
22 for (i = 0; i < 127 && i < length; i++) {
23 opad[i] = opad[i] ^ key[i];
24 ipad[i] = ipad[i] ^ key[i];
27 /* Precompute hash of HMAC OPAD and IPAD to avoid
28 * per packet computation
30 switch (auth_xform->auth.algo) {
31 case RTE_CRYPTO_AUTH_SHA1_HMAC:
32 roc_hash_sha1_gen(opad, (uint32_t *)&hmac_opad_ipad[0]);
33 roc_hash_sha1_gen(ipad, (uint32_t *)&hmac_opad_ipad[24]);
35 case RTE_CRYPTO_AUTH_SHA256_HMAC:
36 roc_hash_sha256_gen(opad, (uint32_t *)&hmac_opad_ipad[0]);
37 roc_hash_sha256_gen(ipad, (uint32_t *)&hmac_opad_ipad[64]);
45 ot_ipsec_sa_common_param_fill(union roc_ot_ipsec_sa_word2 *w2,
46 uint8_t *cipher_key, uint8_t *salt_key,
47 uint8_t *hmac_opad_ipad,
48 struct rte_security_ipsec_xform *ipsec_xfrm,
49 struct rte_crypto_sym_xform *crypto_xfrm)
51 struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm;
58 switch (ipsec_xfrm->direction) {
59 case RTE_SECURITY_IPSEC_SA_DIR_INGRESS:
60 w2->s.dir = ROC_IE_SA_DIR_INBOUND;
61 auth_xfrm = crypto_xfrm;
62 cipher_xfrm = crypto_xfrm->next;
64 case RTE_SECURITY_IPSEC_SA_DIR_EGRESS:
65 w2->s.dir = ROC_IE_SA_DIR_OUTBOUND;
66 cipher_xfrm = crypto_xfrm;
67 auth_xfrm = crypto_xfrm->next;
73 /* Set protocol - ESP vs AH */
74 switch (ipsec_xfrm->proto) {
75 case RTE_SECURITY_IPSEC_SA_PROTO_ESP:
76 w2->s.protocol = ROC_IE_SA_PROTOCOL_ESP;
78 case RTE_SECURITY_IPSEC_SA_PROTO_AH:
79 w2->s.protocol = ROC_IE_SA_PROTOCOL_AH;
85 /* Set mode - transport vs tunnel */
86 switch (ipsec_xfrm->mode) {
87 case RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT:
88 w2->s.mode = ROC_IE_SA_MODE_TRANSPORT;
90 case RTE_SECURITY_IPSEC_SA_MODE_TUNNEL:
91 w2->s.mode = ROC_IE_SA_MODE_TUNNEL;
97 /* Set encryption algorithm */
98 if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
99 key = crypto_xfrm->aead.key.data;
100 length = crypto_xfrm->aead.key.length;
102 switch (crypto_xfrm->aead.algo) {
103 case RTE_CRYPTO_AEAD_AES_GCM:
104 w2->s.enc_type = ROC_IE_OT_SA_ENC_AES_GCM;
105 w2->s.auth_type = ROC_IE_OT_SA_AUTH_NULL;
106 memcpy(salt_key, &ipsec_xfrm->salt, 4);
107 tmp_salt = (uint32_t *)salt_key;
108 *tmp_salt = rte_be_to_cpu_32(*tmp_salt);
114 switch (cipher_xfrm->cipher.algo) {
115 case RTE_CRYPTO_CIPHER_AES_CBC:
116 w2->s.enc_type = ROC_IE_OT_SA_ENC_AES_CBC;
122 switch (auth_xfrm->auth.algo) {
123 case RTE_CRYPTO_AUTH_NULL:
124 w2->s.auth_type = ROC_IE_OT_SA_AUTH_NULL;
126 case RTE_CRYPTO_AUTH_SHA1_HMAC:
127 w2->s.auth_type = ROC_IE_OT_SA_AUTH_SHA1;
128 ipsec_hmac_opad_ipad_gen(auth_xfrm, hmac_opad_ipad);
130 tmp_key = (uint64_t *)hmac_opad_ipad;
131 for (i = 0; i < (int)(ROC_CTX_MAX_OPAD_IPAD_LEN /
134 tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
136 case RTE_CRYPTO_AUTH_SHA256_HMAC:
137 w2->s.auth_type = ROC_IE_OT_SA_AUTH_SHA2_256;
138 ipsec_hmac_opad_ipad_gen(auth_xfrm, hmac_opad_ipad);
140 tmp_key = (uint64_t *)hmac_opad_ipad;
141 for (i = 0; i < (int)(ROC_CTX_MAX_OPAD_IPAD_LEN /
144 tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
150 key = cipher_xfrm->cipher.key.data;
151 length = cipher_xfrm->cipher.key.length;
154 /* Set encapsulation type */
155 if (ipsec_xfrm->options.udp_encap)
156 w2->s.encap_type = ROC_IE_OT_SA_ENCAP_UDP;
158 w2->s.spi = ipsec_xfrm->spi;
160 /* Copy encryption key */
161 memcpy(cipher_key, key, length);
162 tmp_key = (uint64_t *)cipher_key;
163 for (i = 0; i < (int)(ROC_CTX_MAX_CKEY_LEN / sizeof(uint64_t)); i++)
164 tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
167 case ROC_CPT_AES128_KEY_LEN:
168 w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_128;
170 case ROC_CPT_AES192_KEY_LEN:
171 w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_192;
173 case ROC_CPT_AES256_KEY_LEN:
174 w2->s.aes_key_len = ROC_IE_SA_AES_KEY_LEN_256;
180 if (ipsec_xfrm->life.packets_soft_limit != 0 ||
181 ipsec_xfrm->life.packets_hard_limit != 0) {
182 if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
183 ipsec_xfrm->life.bytes_hard_limit != 0) {
184 plt_err("Expiry tracking with both packets & bytes is not supported");
187 w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_PKTS;
190 if (ipsec_xfrm->life.bytes_soft_limit != 0 ||
191 ipsec_xfrm->life.bytes_hard_limit != 0) {
192 if (ipsec_xfrm->life.packets_soft_limit != 0 ||
193 ipsec_xfrm->life.packets_hard_limit != 0) {
194 plt_err("Expiry tracking with both packets & bytes is not supported");
197 w2->s.life_unit = ROC_IE_OT_SA_LIFE_UNIT_OCTETS;
204 ot_ipsec_inb_ctx_size(struct roc_ot_ipsec_inb_sa *sa)
208 /* Variable based on Anti-replay Window */
209 size = offsetof(struct roc_ot_ipsec_inb_sa, ctx) +
210 offsetof(struct roc_ot_ipsec_inb_ctx_update_reg, ar_winbits);
213 size += (1 << (sa->w0.s.ar_win - 1)) * sizeof(uint64_t);
219 ot_ipsec_inb_tunnel_hdr_fill(struct roc_ot_ipsec_inb_sa *sa,
220 struct rte_security_ipsec_xform *ipsec_xfrm)
222 struct rte_security_ipsec_tunnel_param *tunnel;
224 if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
227 if (ipsec_xfrm->options.tunnel_hdr_verify == 0)
230 tunnel = &ipsec_xfrm->tunnel;
232 switch (tunnel->type) {
233 case RTE_SECURITY_IPSEC_TUNNEL_IPV4:
234 sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
235 memcpy(&sa->outer_hdr.ipv4.src_addr, &tunnel->ipv4.src_ip,
236 sizeof(struct in_addr));
237 memcpy(&sa->outer_hdr.ipv4.dst_addr, &tunnel->ipv4.dst_ip,
238 sizeof(struct in_addr));
240 /* IP Source and Dest are in LE/CPU endian */
241 sa->outer_hdr.ipv4.src_addr =
242 rte_be_to_cpu_32(sa->outer_hdr.ipv4.src_addr);
243 sa->outer_hdr.ipv4.dst_addr =
244 rte_be_to_cpu_32(sa->outer_hdr.ipv4.dst_addr);
247 case RTE_SECURITY_IPSEC_TUNNEL_IPV6:
248 sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
249 memcpy(&sa->outer_hdr.ipv6.src_addr, &tunnel->ipv6.src_addr,
250 sizeof(struct in6_addr));
251 memcpy(&sa->outer_hdr.ipv6.dst_addr, &tunnel->ipv6.dst_addr,
252 sizeof(struct in6_addr));
259 switch (ipsec_xfrm->options.tunnel_hdr_verify) {
260 case RTE_SECURITY_IPSEC_TUNNEL_VERIFY_DST_ADDR:
261 sa->w2.s.ip_hdr_verify = ROC_IE_OT_SA_IP_HDR_VERIFY_DST_ADDR;
263 case RTE_SECURITY_IPSEC_TUNNEL_VERIFY_SRC_DST_ADDR:
264 sa->w2.s.ip_hdr_verify =
265 ROC_IE_OT_SA_IP_HDR_VERIFY_SRC_DST_ADDR;
275 cnxk_ot_ipsec_inb_sa_fill(struct roc_ot_ipsec_inb_sa *sa,
276 struct rte_security_ipsec_xform *ipsec_xfrm,
277 struct rte_crypto_sym_xform *crypto_xfrm)
279 union roc_ot_ipsec_sa_word2 w2;
280 uint32_t replay_win_sz;
285 rc = ot_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->w8.s.salt,
286 sa->hmac_opad_ipad, ipsec_xfrm,
291 /* Updata common word2 data */
294 /* Only support power-of-two window sizes supported */
295 replay_win_sz = ipsec_xfrm->replay_win_sz;
297 if (!rte_is_power_of_2(replay_win_sz) ||
298 replay_win_sz > ROC_AR_WIN_SIZE_MAX)
301 sa->w0.s.ar_win = rte_log2_u32(replay_win_sz) - 5;
304 rc = ot_ipsec_inb_tunnel_hdr_fill(sa, ipsec_xfrm);
308 /* Default options for pkt_out and pkt_fmt are with
309 * second pass meta and no defrag.
311 sa->w0.s.pkt_format = ROC_IE_OT_SA_PKT_FMT_META;
312 sa->w0.s.pkt_output = ROC_IE_OT_SA_PKT_OUTPUT_HW_BASED_DEFRAG;
313 sa->w0.s.pkind = ROC_OT_CPT_META_PKIND;
316 sa->w2.s.esn_en = !!ipsec_xfrm->options.esn;
317 if (ipsec_xfrm->options.udp_encap) {
318 sa->w10.s.udp_src_port = 4500;
319 sa->w10.s.udp_dst_port = 4500;
322 if (ipsec_xfrm->options.udp_ports_verify)
323 sa->w2.s.udp_ports_verify = 1;
325 offset = offsetof(struct roc_ot_ipsec_inb_sa, ctx);
326 /* Word offset for HW managed SA field */
327 sa->w0.s.hw_ctx_off = offset / 8;
328 /* Context push size for inbound spans up to hw_ctx including
329 * ar_base field, in 8b units
331 sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off + 1;
332 /* Entire context size in 128B units */
334 (PLT_ALIGN_CEIL(ot_ipsec_inb_ctx_size(sa), ROC_CTX_UNIT_128B) /
339 * CPT MC triggers expiry when counter value changes from 2 to 1. To
340 * mitigate this behaviour add 1 to the life counter values provided.
343 if (ipsec_xfrm->life.bytes_soft_limit) {
344 sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
345 sa->w0.s.soft_life_dec = 1;
348 if (ipsec_xfrm->life.packets_soft_limit) {
349 sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
350 sa->w0.s.soft_life_dec = 1;
353 if (ipsec_xfrm->life.bytes_hard_limit) {
354 sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
355 sa->w0.s.hard_life_dec = 1;
358 if (ipsec_xfrm->life.packets_hard_limit) {
359 sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
360 sa->w0.s.hard_life_dec = 1;
363 /* There are two words of CPT_CTX_HW_S for ucode to skip */
364 sa->w0.s.ctx_hdr_size = 1;
365 sa->w0.s.aop_valid = 1;
366 sa->w0.s.et_ovrwr = 1;
376 cnxk_ot_ipsec_outb_sa_fill(struct roc_ot_ipsec_outb_sa *sa,
377 struct rte_security_ipsec_xform *ipsec_xfrm,
378 struct rte_crypto_sym_xform *crypto_xfrm)
380 struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel;
381 union roc_ot_ipsec_sa_word2 w2;
386 rc = ot_ipsec_sa_common_param_fill(&w2, sa->cipher_key, sa->iv.s.salt,
387 sa->hmac_opad_ipad, ipsec_xfrm,
392 /* Update common word2 data */
395 if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
396 goto skip_tunnel_info;
398 /* Tunnel header info */
399 switch (tunnel->type) {
400 case RTE_SECURITY_IPSEC_TUNNEL_IPV4:
401 sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_4;
402 memcpy(&sa->outer_hdr.ipv4.src_addr, &tunnel->ipv4.src_ip,
403 sizeof(struct in_addr));
404 memcpy(&sa->outer_hdr.ipv4.dst_addr, &tunnel->ipv4.dst_ip,
405 sizeof(struct in_addr));
407 /* IP Source and Dest seems to be in LE/CPU endian */
408 sa->outer_hdr.ipv4.src_addr =
409 rte_be_to_cpu_32(sa->outer_hdr.ipv4.src_addr);
410 sa->outer_hdr.ipv4.dst_addr =
411 rte_be_to_cpu_32(sa->outer_hdr.ipv4.dst_addr);
413 /* Outer header DF bit source */
414 if (!ipsec_xfrm->options.copy_df) {
415 sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
416 ROC_IE_OT_SA_COPY_FROM_SA;
417 sa->w10.s.ipv4_df_or_ipv6_flw_lbl = tunnel->ipv4.df;
419 sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
420 ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
423 /* Outer header DSCP source */
424 if (!ipsec_xfrm->options.copy_dscp) {
425 sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_SA;
426 sa->w10.s.dscp = tunnel->ipv4.dscp;
428 sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
431 case RTE_SECURITY_IPSEC_TUNNEL_IPV6:
432 sa->w2.s.outer_ip_ver = ROC_IE_SA_IP_VERSION_6;
433 memcpy(&sa->outer_hdr.ipv6.src_addr, &tunnel->ipv6.src_addr,
434 sizeof(struct in6_addr));
435 memcpy(&sa->outer_hdr.ipv6.dst_addr, &tunnel->ipv6.dst_addr,
436 sizeof(struct in6_addr));
438 /* Outer header flow label source */
439 if (!ipsec_xfrm->options.copy_flabel) {
440 sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
441 ROC_IE_OT_SA_COPY_FROM_SA;
443 sa->w10.s.ipv4_df_or_ipv6_flw_lbl = tunnel->ipv6.flabel;
445 sa->w2.s.ipv4_df_src_or_ipv6_flw_lbl_src =
446 ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
449 /* Outer header DSCP source */
450 if (!ipsec_xfrm->options.copy_dscp) {
451 sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_SA;
452 sa->w10.s.dscp = tunnel->ipv6.dscp;
454 sa->w2.s.dscp_src = ROC_IE_OT_SA_COPY_FROM_INNER_IP_HDR;
463 sa->w0.s.esn_en = !!ipsec_xfrm->options.esn;
465 if (ipsec_xfrm->options.udp_encap) {
466 sa->w10.s.udp_src_port = 4500;
467 sa->w10.s.udp_dst_port = 4500;
470 offset = offsetof(struct roc_ot_ipsec_outb_sa, ctx);
471 /* Word offset for HW managed SA field */
472 sa->w0.s.hw_ctx_off = offset / 8;
473 /* Context push size is up to hmac_opad_ipad */
474 sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off;
475 /* Entire context size in 128B units */
476 offset = sizeof(struct roc_ot_ipsec_outb_sa);
477 sa->w0.s.ctx_size = (PLT_ALIGN_CEIL(offset, ROC_CTX_UNIT_128B) /
482 sa->w2.s.ipid_gen = 1;
485 * CPT MC triggers expiry when counter value changes from 2 to 1. To
486 * mitigate this behaviour add 1 to the life counter values provided.
489 if (ipsec_xfrm->life.bytes_soft_limit) {
490 sa->ctx.soft_life = ipsec_xfrm->life.bytes_soft_limit + 1;
491 sa->w0.s.soft_life_dec = 1;
494 if (ipsec_xfrm->life.packets_soft_limit) {
495 sa->ctx.soft_life = ipsec_xfrm->life.packets_soft_limit + 1;
496 sa->w0.s.soft_life_dec = 1;
499 if (ipsec_xfrm->life.bytes_hard_limit) {
500 sa->ctx.hard_life = ipsec_xfrm->life.bytes_hard_limit + 1;
501 sa->w0.s.hard_life_dec = 1;
504 if (ipsec_xfrm->life.packets_hard_limit) {
505 sa->ctx.hard_life = ipsec_xfrm->life.packets_hard_limit + 1;
506 sa->w0.s.hard_life_dec = 1;
509 /* There are two words of CPT_CTX_HW_S for ucode to skip */
510 sa->w0.s.ctx_hdr_size = 1;
511 sa->w0.s.aop_valid = 1;
521 cnxk_ot_ipsec_inb_sa_valid(struct roc_ot_ipsec_inb_sa *sa)
523 return !!sa->w2.s.valid;
527 cnxk_ot_ipsec_outb_sa_valid(struct roc_ot_ipsec_outb_sa *sa)
529 return !!sa->w2.s.valid;
533 ipsec_xfrm_verify(struct rte_security_ipsec_xform *ipsec_xfrm,
534 struct rte_crypto_sym_xform *crypto_xfrm)
536 if (crypto_xfrm->next == NULL)
539 if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
540 if (crypto_xfrm->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
541 crypto_xfrm->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
544 if (crypto_xfrm->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
545 crypto_xfrm->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
553 onf_ipsec_sa_common_param_fill(struct roc_ie_onf_sa_ctl *ctl, uint8_t *salt,
554 uint8_t *cipher_key, uint8_t *hmac_opad_ipad,
555 struct rte_security_ipsec_xform *ipsec_xfrm,
556 struct rte_crypto_sym_xform *crypto_xfrm)
558 struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm;
559 int rc, length, auth_key_len;
560 const uint8_t *key = NULL;
563 switch (ipsec_xfrm->direction) {
564 case RTE_SECURITY_IPSEC_SA_DIR_INGRESS:
565 ctl->direction = ROC_IE_SA_DIR_INBOUND;
566 auth_xfrm = crypto_xfrm;
567 cipher_xfrm = crypto_xfrm->next;
569 case RTE_SECURITY_IPSEC_SA_DIR_EGRESS:
570 ctl->direction = ROC_IE_SA_DIR_OUTBOUND;
571 cipher_xfrm = crypto_xfrm;
572 auth_xfrm = crypto_xfrm->next;
578 /* Set protocol - ESP vs AH */
579 switch (ipsec_xfrm->proto) {
580 case RTE_SECURITY_IPSEC_SA_PROTO_ESP:
581 ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP;
583 case RTE_SECURITY_IPSEC_SA_PROTO_AH:
589 /* Set mode - transport vs tunnel */
590 switch (ipsec_xfrm->mode) {
591 case RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT:
592 ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT;
594 case RTE_SECURITY_IPSEC_SA_MODE_TUNNEL:
595 ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL;
601 /* Set encryption algorithm */
602 if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
603 length = crypto_xfrm->aead.key.length;
605 switch (crypto_xfrm->aead.algo) {
606 case RTE_CRYPTO_AEAD_AES_GCM:
607 ctl->enc_type = ROC_IE_ON_SA_ENC_AES_GCM;
608 ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL;
609 memcpy(salt, &ipsec_xfrm->salt, 4);
610 key = crypto_xfrm->aead.key.data;
617 rc = ipsec_xfrm_verify(ipsec_xfrm, crypto_xfrm);
621 switch (cipher_xfrm->cipher.algo) {
622 case RTE_CRYPTO_CIPHER_AES_CBC:
623 ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CBC;
629 switch (auth_xfrm->auth.algo) {
630 case RTE_CRYPTO_AUTH_SHA1_HMAC:
631 ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA1;
636 auth_key_len = auth_xfrm->auth.key.length;
637 if (auth_key_len < 20 || auth_key_len > 64)
640 key = cipher_xfrm->cipher.key.data;
641 length = cipher_xfrm->cipher.key.length;
643 ipsec_hmac_opad_ipad_gen(auth_xfrm, hmac_opad_ipad);
647 case ROC_CPT_AES128_KEY_LEN:
648 ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128;
650 case ROC_CPT_AES192_KEY_LEN:
651 ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192;
653 case ROC_CPT_AES256_KEY_LEN:
654 ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256;
660 memcpy(cipher_key, key, length);
662 if (ipsec_xfrm->options.esn)
665 ctl->spi = rte_cpu_to_be_32(ipsec_xfrm->spi);
670 cnxk_onf_ipsec_inb_sa_fill(struct roc_onf_ipsec_inb_sa *sa,
671 struct rte_security_ipsec_xform *ipsec_xfrm,
672 struct rte_crypto_sym_xform *crypto_xfrm)
674 struct roc_ie_onf_sa_ctl *ctl = &sa->ctl;
677 rc = onf_ipsec_sa_common_param_fill(ctl, sa->nonce, sa->cipher_key,
678 sa->hmac_key, ipsec_xfrm,
691 cnxk_onf_ipsec_outb_sa_fill(struct roc_onf_ipsec_outb_sa *sa,
692 struct rte_security_ipsec_xform *ipsec_xfrm,
693 struct rte_crypto_sym_xform *crypto_xfrm)
695 struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel;
696 struct roc_ie_onf_sa_ctl *ctl = &sa->ctl;
699 /* Fill common params */
700 rc = onf_ipsec_sa_common_param_fill(ctl, sa->nonce, sa->cipher_key,
701 sa->hmac_key, ipsec_xfrm,
706 if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
707 goto skip_tunnel_info;
709 /* Tunnel header info */
710 switch (tunnel->type) {
711 case RTE_SECURITY_IPSEC_TUNNEL_IPV4:
712 memcpy(&sa->ip_src, &tunnel->ipv4.src_ip,
713 sizeof(struct in_addr));
714 memcpy(&sa->ip_dst, &tunnel->ipv4.dst_ip,
715 sizeof(struct in_addr));
717 case RTE_SECURITY_IPSEC_TUNNEL_IPV6:
732 cnxk_onf_ipsec_inb_sa_valid(struct roc_onf_ipsec_inb_sa *sa)
734 return !!sa->ctl.valid;
738 cnxk_onf_ipsec_outb_sa_valid(struct roc_onf_ipsec_outb_sa *sa)
740 return !!sa->ctl.valid;
744 cnxk_ipsec_ivlen_get(enum rte_crypto_cipher_algorithm c_algo,
745 enum rte_crypto_auth_algorithm a_algo,
746 enum rte_crypto_aead_algorithm aead_algo)
750 if (aead_algo == RTE_CRYPTO_AEAD_AES_GCM)
754 case RTE_CRYPTO_CIPHER_AES_CTR:
757 case RTE_CRYPTO_CIPHER_3DES_CBC:
758 ivlen = ROC_CPT_DES_BLOCK_LENGTH;
760 case RTE_CRYPTO_CIPHER_AES_CBC:
761 ivlen = ROC_CPT_AES_BLOCK_LENGTH;
768 case RTE_CRYPTO_AUTH_AES_GMAC:
779 cnxk_ipsec_icvlen_get(enum rte_crypto_cipher_algorithm c_algo,
780 enum rte_crypto_auth_algorithm a_algo,
781 enum rte_crypto_aead_algorithm aead_algo)
788 case RTE_CRYPTO_AUTH_NULL:
791 case RTE_CRYPTO_AUTH_SHA1_HMAC:
794 case RTE_CRYPTO_AUTH_SHA256_HMAC:
795 case RTE_CRYPTO_AUTH_AES_GMAC:
798 case RTE_CRYPTO_AUTH_SHA384_HMAC:
801 case RTE_CRYPTO_AUTH_SHA512_HMAC:
809 case RTE_CRYPTO_AEAD_AES_GCM:
820 cnxk_ipsec_outb_roundup_byte(enum rte_crypto_cipher_algorithm c_algo,
821 enum rte_crypto_aead_algorithm aead_algo)
823 uint8_t roundup_byte = 4;
825 if (aead_algo == RTE_CRYPTO_AEAD_AES_GCM)
829 case RTE_CRYPTO_CIPHER_AES_CTR:
832 case RTE_CRYPTO_CIPHER_AES_CBC:
835 case RTE_CRYPTO_CIPHER_3DES_CBC:
838 case RTE_CRYPTO_CIPHER_NULL:
849 cnxk_ipsec_outb_rlens_get(struct cnxk_ipsec_outb_rlens *rlens,
850 struct rte_security_ipsec_xform *ipsec_xfrm,
851 struct rte_crypto_sym_xform *crypto_xfrm)
853 struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel;
854 enum rte_crypto_cipher_algorithm c_algo = RTE_CRYPTO_CIPHER_NULL;
855 enum rte_crypto_auth_algorithm a_algo = RTE_CRYPTO_AUTH_NULL;
856 enum rte_crypto_aead_algorithm aead_algo = 0;
857 uint16_t partial_len = 0;
858 uint8_t roundup_byte = 0;
859 int8_t roundup_len = 0;
861 memset(rlens, 0, sizeof(struct cnxk_ipsec_outb_rlens));
863 /* Get Cipher and Auth algo */
864 if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
865 aead_algo = crypto_xfrm->aead.algo;
867 if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
868 c_algo = crypto_xfrm->cipher.algo;
870 a_algo = crypto_xfrm->auth.algo;
872 if (crypto_xfrm->next) {
873 if (crypto_xfrm->next->type ==
874 RTE_CRYPTO_SYM_XFORM_CIPHER)
875 c_algo = crypto_xfrm->next->cipher.algo;
877 a_algo = crypto_xfrm->next->auth.algo;
881 if (ipsec_xfrm->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) {
882 partial_len = ROC_CPT_ESP_HDR_LEN;
883 roundup_len = ROC_CPT_ESP_TRL_LEN;
885 partial_len = ROC_CPT_AH_HDR_LEN;
888 if (ipsec_xfrm->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
889 if (tunnel->type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
890 partial_len += ROC_CPT_TUNNEL_IPV4_HDR_LEN;
892 partial_len += ROC_CPT_TUNNEL_IPV6_HDR_LEN;
895 partial_len += cnxk_ipsec_ivlen_get(c_algo, a_algo, aead_algo);
896 partial_len += cnxk_ipsec_icvlen_get(c_algo, a_algo, aead_algo);
897 roundup_byte = cnxk_ipsec_outb_roundup_byte(c_algo, aead_algo);
899 if (ipsec_xfrm->options.udp_encap)
900 partial_len += sizeof(struct rte_udp_hdr);
902 rlens->partial_len = partial_len;
903 rlens->roundup_len = roundup_len;
904 rlens->roundup_byte = roundup_byte;
905 rlens->max_extended_len = partial_len + roundup_len + roundup_byte;