From f3903e772957ea2a5cec933f5758a556429d4444 Mon Sep 17 00:00:00 2001 From: Srujana Challa Date: Fri, 1 Oct 2021 19:09:55 +0530 Subject: [PATCH] common/cnxk: support cn9k fast path security session Add security support to init cn9k fast path SA data for AES GCM and AES CBC + HMAC SHA1. Signed-off-by: Srujana Challa Signed-off-by: Nithin Dabilpuram Acked-by: Jerin Jacob --- drivers/common/cnxk/cnxk_security.c | 211 ++++++++++++++++++++++++++++ drivers/common/cnxk/cnxk_security.h | 12 ++ drivers/common/cnxk/version.map | 4 + 3 files changed, 227 insertions(+) diff --git a/drivers/common/cnxk/cnxk_security.c b/drivers/common/cnxk/cnxk_security.c index cc5daf333c..c117fa70d0 100644 --- a/drivers/common/cnxk/cnxk_security.c +++ b/drivers/common/cnxk/cnxk_security.c @@ -513,6 +513,217 @@ cnxk_ot_ipsec_outb_sa_valid(struct roc_ot_ipsec_outb_sa *sa) return !!sa->w2.s.valid; } +static inline int +ipsec_xfrm_verify(struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm) +{ + if (crypto_xfrm->next == NULL) + return -EINVAL; + + if (ipsec_xfrm->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) { + if (crypto_xfrm->type != RTE_CRYPTO_SYM_XFORM_AUTH || + crypto_xfrm->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER) + return -EINVAL; + } else { + if (crypto_xfrm->type != RTE_CRYPTO_SYM_XFORM_CIPHER || + crypto_xfrm->next->type != RTE_CRYPTO_SYM_XFORM_AUTH) + return -EINVAL; + } + + return 0; +} + +static int +onf_ipsec_sa_common_param_fill(struct roc_ie_onf_sa_ctl *ctl, uint8_t *salt, + uint8_t *cipher_key, uint8_t *hmac_opad_ipad, + struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm) +{ + struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm; + int rc, length, auth_key_len; + const uint8_t *key = NULL; + + /* Set direction */ + switch (ipsec_xfrm->direction) { + case RTE_SECURITY_IPSEC_SA_DIR_INGRESS: + ctl->direction = ROC_IE_SA_DIR_INBOUND; + auth_xfrm = crypto_xfrm; + cipher_xfrm = crypto_xfrm->next; + break; + case RTE_SECURITY_IPSEC_SA_DIR_EGRESS: + ctl->direction = ROC_IE_SA_DIR_OUTBOUND; + cipher_xfrm = crypto_xfrm; + auth_xfrm = crypto_xfrm->next; + break; + default: + return -EINVAL; + } + + /* Set protocol - ESP vs AH */ + switch (ipsec_xfrm->proto) { + case RTE_SECURITY_IPSEC_SA_PROTO_ESP: + ctl->ipsec_proto = ROC_IE_SA_PROTOCOL_ESP; + break; + case RTE_SECURITY_IPSEC_SA_PROTO_AH: + return -ENOTSUP; + default: + return -EINVAL; + } + + /* Set mode - transport vs tunnel */ + switch (ipsec_xfrm->mode) { + case RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT: + ctl->ipsec_mode = ROC_IE_SA_MODE_TRANSPORT; + break; + case RTE_SECURITY_IPSEC_SA_MODE_TUNNEL: + ctl->ipsec_mode = ROC_IE_SA_MODE_TUNNEL; + break; + default: + return -EINVAL; + } + + /* Set encryption algorithm */ + if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) { + length = crypto_xfrm->aead.key.length; + + switch (crypto_xfrm->aead.algo) { + case RTE_CRYPTO_AEAD_AES_GCM: + ctl->enc_type = ROC_IE_ON_SA_ENC_AES_GCM; + ctl->auth_type = ROC_IE_ON_SA_AUTH_NULL; + memcpy(salt, &ipsec_xfrm->salt, 4); + key = crypto_xfrm->aead.key.data; + break; + default: + return -ENOTSUP; + } + + } else { + rc = ipsec_xfrm_verify(ipsec_xfrm, crypto_xfrm); + if (rc) + return rc; + + switch (cipher_xfrm->cipher.algo) { + case RTE_CRYPTO_CIPHER_AES_CBC: + ctl->enc_type = ROC_IE_ON_SA_ENC_AES_CBC; + break; + default: + return -ENOTSUP; + } + + switch (auth_xfrm->auth.algo) { + case RTE_CRYPTO_AUTH_SHA1_HMAC: + ctl->auth_type = ROC_IE_ON_SA_AUTH_SHA1; + break; + default: + return -ENOTSUP; + } + auth_key_len = auth_xfrm->auth.key.length; + if (auth_key_len < 20 || auth_key_len > 64) + return -ENOTSUP; + + key = cipher_xfrm->cipher.key.data; + length = cipher_xfrm->cipher.key.length; + + ipsec_hmac_opad_ipad_gen(auth_xfrm, hmac_opad_ipad); + } + + switch (length) { + case ROC_CPT_AES128_KEY_LEN: + ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_128; + break; + case ROC_CPT_AES192_KEY_LEN: + ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_192; + break; + case ROC_CPT_AES256_KEY_LEN: + ctl->aes_key_len = ROC_IE_SA_AES_KEY_LEN_256; + break; + default: + return -EINVAL; + } + + memcpy(cipher_key, key, length); + + if (ipsec_xfrm->options.esn) + ctl->esn_en = 1; + + ctl->spi = rte_cpu_to_be_32(ipsec_xfrm->spi); + return 0; +} + +int +cnxk_onf_ipsec_inb_sa_fill(struct roc_onf_ipsec_inb_sa *sa, + struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm) +{ + struct roc_ie_onf_sa_ctl *ctl = &sa->ctl; + int rc; + + rc = onf_ipsec_sa_common_param_fill(ctl, sa->nonce, sa->cipher_key, + sa->hmac_key, ipsec_xfrm, + crypto_xfrm); + if (rc) + return rc; + + rte_wmb(); + + /* Enable SA */ + ctl->valid = 1; + return 0; +} + +int +cnxk_onf_ipsec_outb_sa_fill(struct roc_onf_ipsec_outb_sa *sa, + struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm) +{ + struct rte_security_ipsec_tunnel_param *tunnel = &ipsec_xfrm->tunnel; + struct roc_ie_onf_sa_ctl *ctl = &sa->ctl; + int rc; + + /* Fill common params */ + rc = onf_ipsec_sa_common_param_fill(ctl, sa->nonce, sa->cipher_key, + sa->hmac_key, ipsec_xfrm, + crypto_xfrm); + if (rc) + return rc; + + if (ipsec_xfrm->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) + goto skip_tunnel_info; + + /* Tunnel header info */ + switch (tunnel->type) { + case RTE_SECURITY_IPSEC_TUNNEL_IPV4: + memcpy(&sa->ip_src, &tunnel->ipv4.src_ip, + sizeof(struct in_addr)); + memcpy(&sa->ip_dst, &tunnel->ipv4.dst_ip, + sizeof(struct in_addr)); + break; + case RTE_SECURITY_IPSEC_TUNNEL_IPV6: + return -ENOTSUP; + default: + return -EINVAL; + } + +skip_tunnel_info: + rte_wmb(); + + /* Enable SA */ + ctl->valid = 1; + return 0; +} + +bool +cnxk_onf_ipsec_inb_sa_valid(struct roc_onf_ipsec_inb_sa *sa) +{ + return !!sa->ctl.valid; +} + +bool +cnxk_onf_ipsec_outb_sa_valid(struct roc_onf_ipsec_outb_sa *sa) +{ + return !!sa->ctl.valid; +} + uint8_t cnxk_ipsec_ivlen_get(enum rte_crypto_cipher_algorithm c_algo, enum rte_crypto_auth_algorithm a_algo, diff --git a/drivers/common/cnxk/cnxk_security.h b/drivers/common/cnxk/cnxk_security.h index 602f583600..db97887010 100644 --- a/drivers/common/cnxk/cnxk_security.h +++ b/drivers/common/cnxk/cnxk_security.h @@ -46,4 +46,16 @@ cnxk_ot_ipsec_outb_sa_fill(struct roc_ot_ipsec_outb_sa *sa, bool __roc_api cnxk_ot_ipsec_inb_sa_valid(struct roc_ot_ipsec_inb_sa *sa); bool __roc_api cnxk_ot_ipsec_outb_sa_valid(struct roc_ot_ipsec_outb_sa *sa); +/* [CN9K, CN10K) */ +int __roc_api +cnxk_onf_ipsec_inb_sa_fill(struct roc_onf_ipsec_inb_sa *sa, + struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm); +int __roc_api +cnxk_onf_ipsec_outb_sa_fill(struct roc_onf_ipsec_outb_sa *sa, + struct rte_security_ipsec_xform *ipsec_xfrm, + struct rte_crypto_sym_xform *crypto_xfrm); +bool __roc_api cnxk_onf_ipsec_inb_sa_valid(struct roc_onf_ipsec_inb_sa *sa); +bool __roc_api cnxk_onf_ipsec_outb_sa_valid(struct roc_onf_ipsec_outb_sa *sa); + #endif /* _CNXK_SECURITY_H__ */ diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map index fff7902b25..f7b6ef68e9 100644 --- a/drivers/common/cnxk/version.map +++ b/drivers/common/cnxk/version.map @@ -14,6 +14,10 @@ INTERNAL { cnxk_logtype_sso; cnxk_logtype_tim; cnxk_logtype_tm; + cnxk_onf_ipsec_inb_sa_fill; + cnxk_onf_ipsec_outb_sa_fill; + cnxk_onf_ipsec_inb_sa_valid; + cnxk_onf_ipsec_outb_sa_valid; cnxk_ot_ipsec_inb_sa_fill; cnxk_ot_ipsec_outb_sa_fill; cnxk_ot_ipsec_inb_sa_valid; -- 2.20.1