X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fcrypto%2Focteontx2%2Fotx2_ipsec_po.h;h=b3e7456551cfeea51a66220795b3362632e883c8;hb=3841fc3581ec4d95bf8a72e8a545db8d03ecd2bd;hp=217dfeaff03bdb8dfdc22a0d718bfe5a892fdd3a;hpb=e6c1223dd5cef644f2975e819410d4d116552b1a;p=dpdk.git diff --git a/drivers/crypto/octeontx2/otx2_ipsec_po.h b/drivers/crypto/octeontx2/otx2_ipsec_po.h index 217dfeaff0..b3e7456551 100644 --- a/drivers/crypto/octeontx2/otx2_ipsec_po.h +++ b/drivers/crypto/octeontx2/otx2_ipsec_po.h @@ -9,6 +9,93 @@ #include #include +#define OTX2_IPSEC_PO_AES_GCM_INB_CTX_LEN 0x09 + +#define OTX2_IPSEC_PO_PER_PKT_IV BIT(11) + +#define OTX2_IPSEC_PO_WRITE_IPSEC_OUTB 0x20 +#define OTX2_IPSEC_PO_WRITE_IPSEC_INB 0x21 +#define OTX2_IPSEC_PO_PROCESS_IPSEC_OUTB 0x23 +#define OTX2_IPSEC_PO_PROCESS_IPSEC_INB 0x24 + +#define OTX2_IPSEC_PO_INB_RPTR_HDR 0x8 + +enum otx2_ipsec_po_mode_type { + OTX2_IPSEC_PO_TRANSPORT = 1, + OTX2_IPSEC_PO_TUNNEL_IPV4, + OTX2_IPSEC_PO_TUNNEL_IPV6, +}; + +enum otx2_ipsec_po_comp_e { + OTX2_IPSEC_PO_CC_SUCCESS = 0x00, + OTX2_IPSEC_PO_CC_AUTH_UNSUPPORTED = 0xB0, + OTX2_IPSEC_PO_CC_ENCRYPT_UNSUPPORTED = 0xB1, +}; + +enum { + OTX2_IPSEC_PO_SA_DIRECTION_INBOUND = 0, + OTX2_IPSEC_PO_SA_DIRECTION_OUTBOUND = 1, +}; + +enum { + OTX2_IPSEC_PO_SA_IP_VERSION_4 = 0, + OTX2_IPSEC_PO_SA_IP_VERSION_6 = 1, +}; + +enum { + OTX2_IPSEC_PO_SA_MODE_TRANSPORT = 0, + OTX2_IPSEC_PO_SA_MODE_TUNNEL = 1, +}; + +enum { + OTX2_IPSEC_PO_SA_PROTOCOL_AH = 0, + OTX2_IPSEC_PO_SA_PROTOCOL_ESP = 1, +}; + +enum { + OTX2_IPSEC_PO_SA_AES_KEY_LEN_128 = 1, + OTX2_IPSEC_PO_SA_AES_KEY_LEN_192 = 2, + OTX2_IPSEC_PO_SA_AES_KEY_LEN_256 = 3, +}; + +enum { + OTX2_IPSEC_PO_SA_ENC_NULL = 0, + OTX2_IPSEC_PO_SA_ENC_DES_CBC = 1, + OTX2_IPSEC_PO_SA_ENC_3DES_CBC = 2, + OTX2_IPSEC_PO_SA_ENC_AES_CBC = 3, + OTX2_IPSEC_PO_SA_ENC_AES_CTR = 4, + OTX2_IPSEC_PO_SA_ENC_AES_GCM = 5, + OTX2_IPSEC_PO_SA_ENC_AES_CCM = 6, +}; + +enum { + OTX2_IPSEC_PO_SA_AUTH_NULL = 0, + OTX2_IPSEC_PO_SA_AUTH_MD5 = 1, + OTX2_IPSEC_PO_SA_AUTH_SHA1 = 2, + OTX2_IPSEC_PO_SA_AUTH_SHA2_224 = 3, + OTX2_IPSEC_PO_SA_AUTH_SHA2_256 = 4, + OTX2_IPSEC_PO_SA_AUTH_SHA2_384 = 5, + OTX2_IPSEC_PO_SA_AUTH_SHA2_512 = 6, + OTX2_IPSEC_PO_SA_AUTH_AES_GMAC = 7, + OTX2_IPSEC_PO_SA_AUTH_AES_XCBC_128 = 8, +}; + +enum { + OTX2_IPSEC_PO_SA_FRAG_POST = 0, + OTX2_IPSEC_PO_SA_FRAG_PRE = 1, +}; + +enum { + OTX2_IPSEC_PO_SA_ENCAP_NONE = 0, + OTX2_IPSEC_PO_SA_ENCAP_UDP = 1, +}; + +struct otx2_ipsec_po_out_hdr { + uint32_t ip_id; + uint32_t seq; + uint8_t iv[16]; +}; + union otx2_ipsec_po_bit_perfect_iv { uint8_t aes_iv[16]; uint8_t des_iv[8]; @@ -71,19 +158,38 @@ struct otx2_ipsec_po_in_sa { /* w8 */ uint8_t udp_encap[8]; - /* w9-w23 */ - struct { - uint8_t hmac_key[48]; - struct otx2_ipsec_po_traffic_selector selector; - } aes_gcm; + /* w9-w33 */ + union { + struct { + uint8_t hmac_key[48]; + struct otx2_ipsec_po_traffic_selector selector; + } aes_gcm; + struct { + uint8_t hmac_key[64]; + uint8_t hmac_iv[64]; + struct otx2_ipsec_po_traffic_selector selector; + } sha2; + }; + union { + struct otx2_ipsec_replay *replay; + uint64_t replay64; + }; + uint32_t replay_win_sz; }; struct otx2_ipsec_po_ip_template { RTE_STD_C11 union { - uint8_t raw[252]; - struct rte_ipv4_hdr ipv4_hdr; - struct rte_ipv6_hdr ipv6_hdr; + struct { + struct rte_ipv4_hdr ipv4_hdr; + uint16_t udp_src; + uint16_t udp_dst; + } ip4; + struct { + struct rte_ipv6_hdr ipv6_hdr; + uint16_t udp_src; + uint16_t udp_dst; + } ip6; }; }; @@ -101,10 +207,243 @@ struct otx2_ipsec_po_out_sa { uint32_t esn_hi; uint32_t esn_low; - /* w8-w39 */ - struct otx2_ipsec_po_ip_template template; - uint16_t udp_src; - uint16_t udp_dst; + /* w8-w55 */ + union { + struct { + struct otx2_ipsec_po_ip_template template; + } aes_gcm; + struct { + uint8_t hmac_key[24]; + uint8_t unused[24]; + struct otx2_ipsec_po_ip_template template; + } sha1; + struct { + uint8_t hmac_key[64]; + uint8_t hmac_iv[64]; + struct otx2_ipsec_po_ip_template template; + } sha2; + }; }; +static inline int +ipsec_po_xform_cipher_verify(struct rte_crypto_sym_xform *xform) +{ + if (xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) { + switch (xform->cipher.key.length) { + case 16: + case 24: + case 32: + break; + default: + return -ENOTSUP; + } + return 0; + } + + return -ENOTSUP; +} + +static inline int +ipsec_po_xform_auth_verify(struct rte_crypto_sym_xform *xform) +{ + uint16_t keylen = xform->auth.key.length; + + if (xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) { + if (keylen >= 20 && keylen <= 64) + return 0; + } else if (xform->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC) { + if (keylen >= 32 && keylen <= 64) + return 0; + } + + return -ENOTSUP; +} + +static inline int +ipsec_po_xform_aead_verify(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *xform) +{ + if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS && + xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT) + return -EINVAL; + + if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS && + xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT) + return -EINVAL; + + if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) { + switch (xform->aead.key.length) { + case 16: + case 24: + case 32: + break; + default: + return -EINVAL; + } + return 0; + } + + return -ENOTSUP; +} + +static inline int +ipsec_po_xform_verify(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *xform) +{ + struct rte_crypto_sym_xform *auth_xform, *cipher_xform; + int ret; + + if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) + return ipsec_po_xform_aead_verify(ipsec, xform); + + if (xform->next == NULL) + return -EINVAL; + + if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { + /* Ingress */ + if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH || + xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER) + return -EINVAL; + auth_xform = xform; + cipher_xform = xform->next; + } else { + /* Egress */ + if (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER || + xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH) + return -EINVAL; + cipher_xform = xform; + auth_xform = xform->next; + } + + ret = ipsec_po_xform_cipher_verify(cipher_xform); + if (ret) + return ret; + + ret = ipsec_po_xform_auth_verify(auth_xform); + if (ret) + return ret; + + return 0; +} + +static inline int +ipsec_po_sa_ctl_set(struct rte_security_ipsec_xform *ipsec, + struct rte_crypto_sym_xform *xform, + struct otx2_ipsec_po_sa_ctl *ctl) +{ + struct rte_crypto_sym_xform *cipher_xform, *auth_xform; + int aes_key_len; + + if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) { + ctl->direction = OTX2_IPSEC_PO_SA_DIRECTION_OUTBOUND; + cipher_xform = xform; + auth_xform = xform->next; + } else if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { + ctl->direction = OTX2_IPSEC_PO_SA_DIRECTION_INBOUND; + auth_xform = xform; + cipher_xform = xform->next; + } else { + return -EINVAL; + } + + if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) { + if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4) + ctl->outer_ip_ver = OTX2_IPSEC_PO_SA_IP_VERSION_4; + else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6) + ctl->outer_ip_ver = OTX2_IPSEC_PO_SA_IP_VERSION_6; + else + return -EINVAL; + } + + ctl->inner_ip_ver = ctl->outer_ip_ver; + + if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) + ctl->ipsec_mode = OTX2_IPSEC_PO_SA_MODE_TRANSPORT; + else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) + ctl->ipsec_mode = OTX2_IPSEC_PO_SA_MODE_TUNNEL; + else + return -EINVAL; + + if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) + ctl->ipsec_proto = OTX2_IPSEC_PO_SA_PROTOCOL_AH; + else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP) + ctl->ipsec_proto = OTX2_IPSEC_PO_SA_PROTOCOL_ESP; + else + return -EINVAL; + + if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) { + if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) { + ctl->enc_type = OTX2_IPSEC_PO_SA_ENC_AES_GCM; + aes_key_len = xform->aead.key.length; + } else { + return -ENOTSUP; + } + } else if (cipher_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) { + ctl->enc_type = OTX2_IPSEC_PO_SA_ENC_AES_CBC; + aes_key_len = cipher_xform->cipher.key.length; + } else { + return -ENOTSUP; + } + + + switch (aes_key_len) { + case 16: + ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_128; + break; + case 24: + ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_192; + break; + case 32: + ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_256; + break; + default: + return -EINVAL; + } + + if (xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) { + switch (auth_xform->auth.algo) { + case RTE_CRYPTO_AUTH_NULL: + ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_NULL; + break; + case RTE_CRYPTO_AUTH_MD5_HMAC: + ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_MD5; + break; + case RTE_CRYPTO_AUTH_SHA1_HMAC: + ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA1; + break; + case RTE_CRYPTO_AUTH_SHA224_HMAC: + ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_224; + break; + case RTE_CRYPTO_AUTH_SHA256_HMAC: + ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_256; + break; + case RTE_CRYPTO_AUTH_SHA384_HMAC: + ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_384; + break; + case RTE_CRYPTO_AUTH_SHA512_HMAC: + ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_512; + break; + case RTE_CRYPTO_AUTH_AES_GMAC: + ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_AES_GMAC; + break; + case RTE_CRYPTO_AUTH_AES_XCBC_MAC: + ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_AES_XCBC_128; + break; + default: + return -ENOTSUP; + } + } + + if (ipsec->options.esn) + ctl->esn_en = 1; + + if (ipsec->options.udp_encap == 1) + ctl->encap_type = OTX2_IPSEC_PO_SA_ENCAP_UDP; + + ctl->spi = rte_cpu_to_be_32(ipsec->spi); + ctl->valid = 1; + + return 0; +} + #endif /* __OTX2_IPSEC_PO_H__ */