1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(C) 2020 Marvell International Ltd.
5 #ifndef __OTX2_IPSEC_PO_H__
6 #define __OTX2_IPSEC_PO_H__
8 #include <rte_crypto_sym.h>
10 #include <rte_security.h>
12 #define OTX2_IPSEC_PO_AES_GCM_INB_CTX_LEN 0x09
14 #define OTX2_IPSEC_PO_PER_PKT_IV BIT(11)
16 #define OTX2_IPSEC_PO_WRITE_IPSEC_OUTB 0x20
17 #define OTX2_IPSEC_PO_WRITE_IPSEC_INB 0x21
18 #define OTX2_IPSEC_PO_PROCESS_IPSEC_OUTB 0x23
19 #define OTX2_IPSEC_PO_PROCESS_IPSEC_INB 0x24
21 #define OTX2_IPSEC_PO_INB_RPTR_HDR 0x8
23 enum otx2_ipsec_po_mode_type {
24 OTX2_IPSEC_PO_TRANSPORT = 1,
25 OTX2_IPSEC_PO_TUNNEL_IPV4,
26 OTX2_IPSEC_PO_TUNNEL_IPV6,
29 enum otx2_ipsec_po_comp_e {
30 OTX2_IPSEC_PO_CC_SUCCESS = 0x00,
31 OTX2_IPSEC_PO_CC_AUTH_UNSUPPORTED = 0xB0,
32 OTX2_IPSEC_PO_CC_ENCRYPT_UNSUPPORTED = 0xB1,
36 OTX2_IPSEC_PO_SA_DIRECTION_INBOUND = 0,
37 OTX2_IPSEC_PO_SA_DIRECTION_OUTBOUND = 1,
41 OTX2_IPSEC_PO_SA_IP_VERSION_4 = 0,
42 OTX2_IPSEC_PO_SA_IP_VERSION_6 = 1,
46 OTX2_IPSEC_PO_SA_MODE_TRANSPORT = 0,
47 OTX2_IPSEC_PO_SA_MODE_TUNNEL = 1,
51 OTX2_IPSEC_PO_SA_PROTOCOL_AH = 0,
52 OTX2_IPSEC_PO_SA_PROTOCOL_ESP = 1,
56 OTX2_IPSEC_PO_SA_AES_KEY_LEN_128 = 1,
57 OTX2_IPSEC_PO_SA_AES_KEY_LEN_192 = 2,
58 OTX2_IPSEC_PO_SA_AES_KEY_LEN_256 = 3,
62 OTX2_IPSEC_PO_SA_ENC_NULL = 0,
63 OTX2_IPSEC_PO_SA_ENC_DES_CBC = 1,
64 OTX2_IPSEC_PO_SA_ENC_3DES_CBC = 2,
65 OTX2_IPSEC_PO_SA_ENC_AES_CBC = 3,
66 OTX2_IPSEC_PO_SA_ENC_AES_CTR = 4,
67 OTX2_IPSEC_PO_SA_ENC_AES_GCM = 5,
68 OTX2_IPSEC_PO_SA_ENC_AES_CCM = 6,
72 OTX2_IPSEC_PO_SA_AUTH_NULL = 0,
73 OTX2_IPSEC_PO_SA_AUTH_MD5 = 1,
74 OTX2_IPSEC_PO_SA_AUTH_SHA1 = 2,
75 OTX2_IPSEC_PO_SA_AUTH_SHA2_224 = 3,
76 OTX2_IPSEC_PO_SA_AUTH_SHA2_256 = 4,
77 OTX2_IPSEC_PO_SA_AUTH_SHA2_384 = 5,
78 OTX2_IPSEC_PO_SA_AUTH_SHA2_512 = 6,
79 OTX2_IPSEC_PO_SA_AUTH_AES_GMAC = 7,
80 OTX2_IPSEC_PO_SA_AUTH_AES_XCBC_128 = 8,
84 OTX2_IPSEC_PO_SA_FRAG_POST = 0,
85 OTX2_IPSEC_PO_SA_FRAG_PRE = 1,
89 OTX2_IPSEC_PO_SA_ENCAP_NONE = 0,
90 OTX2_IPSEC_PO_SA_ENCAP_UDP = 1,
93 struct otx2_ipsec_po_out_hdr {
99 union otx2_ipsec_po_bit_perfect_iv {
109 struct otx2_ipsec_po_traffic_selector {
110 rte_be16_t src_port[2];
111 rte_be16_t dst_port[2];
115 rte_be32_t src_addr[2];
116 rte_be32_t dst_addr[2];
119 uint8_t src_addr[32];
120 uint8_t dst_addr[32];
125 struct otx2_ipsec_po_sa_ctl {
127 uint64_t exp_proto_inter_frag : 8;
128 uint64_t rsvd_42_40 : 3;
130 uint64_t rsvd_45_44 : 2;
131 uint64_t encap_type : 2;
132 uint64_t enc_type : 3;
133 uint64_t rsvd_48 : 1;
134 uint64_t auth_type : 4;
136 uint64_t direction : 1;
137 uint64_t outer_ip_ver : 1;
138 uint64_t inner_ip_ver : 1;
139 uint64_t ipsec_mode : 1;
140 uint64_t ipsec_proto : 1;
141 uint64_t aes_key_len : 2;
144 struct otx2_ipsec_po_in_sa {
146 struct otx2_ipsec_po_sa_ctl ctl;
149 uint8_t cipher_key[32];
152 union otx2_ipsec_po_bit_perfect_iv iv;
159 uint8_t udp_encap[8];
164 uint8_t hmac_key[48];
165 struct otx2_ipsec_po_traffic_selector selector;
168 uint8_t hmac_key[64];
170 struct otx2_ipsec_po_traffic_selector selector;
174 struct otx2_ipsec_replay *replay;
177 uint32_t replay_win_sz;
180 struct otx2_ipsec_po_ip_template {
184 struct rte_ipv4_hdr ipv4_hdr;
189 struct rte_ipv6_hdr ipv6_hdr;
196 struct otx2_ipsec_po_out_sa {
198 struct otx2_ipsec_po_sa_ctl ctl;
201 uint8_t cipher_key[32];
204 union otx2_ipsec_po_bit_perfect_iv iv;
213 struct otx2_ipsec_po_ip_template template;
216 uint8_t hmac_key[24];
218 struct otx2_ipsec_po_ip_template template;
221 uint8_t hmac_key[64];
223 struct otx2_ipsec_po_ip_template template;
229 ipsec_po_xform_cipher_verify(struct rte_crypto_sym_xform *xform)
231 if (xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
232 switch (xform->cipher.key.length) {
247 ipsec_po_xform_auth_verify(struct rte_crypto_sym_xform *xform)
249 uint16_t keylen = xform->auth.key.length;
251 if (xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) {
252 if (keylen >= 20 && keylen <= 64)
254 } else if (xform->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC) {
255 if (keylen >= 32 && keylen <= 64)
263 ipsec_po_xform_aead_verify(struct rte_security_ipsec_xform *ipsec,
264 struct rte_crypto_sym_xform *xform)
266 if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
267 xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
270 if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
271 xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
274 if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
275 switch (xform->aead.key.length) {
290 ipsec_po_xform_verify(struct rte_security_ipsec_xform *ipsec,
291 struct rte_crypto_sym_xform *xform)
293 struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
296 if (ipsec->life.bytes_hard_limit != 0 ||
297 ipsec->life.bytes_soft_limit != 0 ||
298 ipsec->life.packets_hard_limit != 0 ||
299 ipsec->life.packets_soft_limit != 0)
302 if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
303 return ipsec_po_xform_aead_verify(ipsec, xform);
305 if (xform->next == NULL)
308 if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
310 if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
311 xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
314 cipher_xform = xform->next;
317 if (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
318 xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
320 cipher_xform = xform;
321 auth_xform = xform->next;
324 ret = ipsec_po_xform_cipher_verify(cipher_xform);
328 ret = ipsec_po_xform_auth_verify(auth_xform);
336 ipsec_po_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
337 struct rte_crypto_sym_xform *xform,
338 struct otx2_ipsec_po_sa_ctl *ctl)
340 struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
343 if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
344 ctl->direction = OTX2_IPSEC_PO_SA_DIRECTION_OUTBOUND;
345 cipher_xform = xform;
346 auth_xform = xform->next;
347 } else if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
348 ctl->direction = OTX2_IPSEC_PO_SA_DIRECTION_INBOUND;
350 cipher_xform = xform->next;
355 if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
356 if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
357 ctl->outer_ip_ver = OTX2_IPSEC_PO_SA_IP_VERSION_4;
358 else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
359 ctl->outer_ip_ver = OTX2_IPSEC_PO_SA_IP_VERSION_6;
364 ctl->inner_ip_ver = ctl->outer_ip_ver;
366 if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT)
367 ctl->ipsec_mode = OTX2_IPSEC_PO_SA_MODE_TRANSPORT;
368 else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
369 ctl->ipsec_mode = OTX2_IPSEC_PO_SA_MODE_TUNNEL;
373 if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
374 ctl->ipsec_proto = OTX2_IPSEC_PO_SA_PROTOCOL_AH;
375 else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP)
376 ctl->ipsec_proto = OTX2_IPSEC_PO_SA_PROTOCOL_ESP;
380 if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
381 if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
382 ctl->enc_type = OTX2_IPSEC_PO_SA_ENC_AES_GCM;
383 aes_key_len = xform->aead.key.length;
387 } else if (cipher_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
388 ctl->enc_type = OTX2_IPSEC_PO_SA_ENC_AES_CBC;
389 aes_key_len = cipher_xform->cipher.key.length;
395 switch (aes_key_len) {
397 ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_128;
400 ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_192;
403 ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_256;
409 if (xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
410 switch (auth_xform->auth.algo) {
411 case RTE_CRYPTO_AUTH_NULL:
412 ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_NULL;
414 case RTE_CRYPTO_AUTH_MD5_HMAC:
415 ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_MD5;
417 case RTE_CRYPTO_AUTH_SHA1_HMAC:
418 ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA1;
420 case RTE_CRYPTO_AUTH_SHA224_HMAC:
421 ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_224;
423 case RTE_CRYPTO_AUTH_SHA256_HMAC:
424 ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_256;
426 case RTE_CRYPTO_AUTH_SHA384_HMAC:
427 ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_384;
429 case RTE_CRYPTO_AUTH_SHA512_HMAC:
430 ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_512;
432 case RTE_CRYPTO_AUTH_AES_GMAC:
433 ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_AES_GMAC;
435 case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
436 ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_AES_XCBC_128;
443 if (ipsec->options.esn)
446 if (ipsec->options.udp_encap == 1)
447 ctl->encap_type = OTX2_IPSEC_PO_SA_ENCAP_UDP;
449 ctl->spi = rte_cpu_to_be_32(ipsec->spi);
455 #endif /* __OTX2_IPSEC_PO_H__ */