From 685e289024b233459bc0b084fbbb9513341fab4d Mon Sep 17 00:00:00 2001 From: Anoob Joseph Date: Fri, 25 Jun 2021 11:26:20 +0530 Subject: [PATCH] crypto/cnxk: add auth operation in session Add support for auth operations in session. Signed-off-by: Ankur Dwivedi Signed-off-by: Anoob Joseph Signed-off-by: Archana Muniganti Signed-off-by: Tejasree Kondoj Acked-by: Akhil Goyal --- drivers/crypto/cnxk/cnxk_cryptodev_ops.c | 13 ++ drivers/crypto/cnxk/cnxk_se.h | 194 +++++++++++++++++++++++ 2 files changed, 207 insertions(+) diff --git a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c index b6d307649f..f2319df92f 100644 --- a/drivers/crypto/cnxk/cnxk_cryptodev_ops.c +++ b/drivers/crypto/cnxk/cnxk_cryptodev_ops.c @@ -460,6 +460,12 @@ sym_session_configure(struct roc_cpt *roc_cpt, int driver_id, case CNXK_CPT_CIPHER: ret = fill_sess_cipher(xform, sess_priv); break; + case CNXK_CPT_AUTH: + if (xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) + ret = fill_sess_gmac(xform, sess_priv); + else + ret = fill_sess_auth(xform, sess_priv); + break; default: ret = -1; } @@ -467,6 +473,13 @@ sym_session_configure(struct roc_cpt *roc_cpt, int driver_id, if (ret) goto priv_put; + if ((sess_priv->roc_se_ctx.fc_type == ROC_SE_HASH_HMAC) && + cpt_mac_len_verify(&xform->auth)) { + plt_dp_err("MAC length is not supported"); + ret = -ENOTSUP; + goto priv_put; + } + sess_priv->cpt_inst_w7 = cnxk_cpt_inst_w7_get(sess_priv, roc_cpt); set_sym_session_private_data(sess, driver_id, sess_priv); diff --git a/drivers/crypto/cnxk/cnxk_se.h b/drivers/crypto/cnxk/cnxk_se.h index b5a16c4dbf..6e4b0321e4 100644 --- a/drivers/crypto/cnxk/cnxk_se.h +++ b/drivers/crypto/cnxk/cnxk_se.h @@ -28,6 +28,48 @@ struct cnxk_se_sess { struct roc_se_ctx roc_se_ctx; } __rte_cache_aligned; +static __rte_always_inline int +cpt_mac_len_verify(struct rte_crypto_auth_xform *auth) +{ + uint16_t mac_len = auth->digest_length; + int ret; + + switch (auth->algo) { + case RTE_CRYPTO_AUTH_MD5: + case RTE_CRYPTO_AUTH_MD5_HMAC: + ret = (mac_len == 16) ? 0 : -1; + break; + case RTE_CRYPTO_AUTH_SHA1: + case RTE_CRYPTO_AUTH_SHA1_HMAC: + ret = (mac_len == 20) ? 0 : -1; + break; + case RTE_CRYPTO_AUTH_SHA224: + case RTE_CRYPTO_AUTH_SHA224_HMAC: + ret = (mac_len == 28) ? 0 : -1; + break; + case RTE_CRYPTO_AUTH_SHA256: + case RTE_CRYPTO_AUTH_SHA256_HMAC: + ret = (mac_len == 32) ? 0 : -1; + break; + case RTE_CRYPTO_AUTH_SHA384: + case RTE_CRYPTO_AUTH_SHA384_HMAC: + ret = (mac_len == 48) ? 0 : -1; + break; + case RTE_CRYPTO_AUTH_SHA512: + case RTE_CRYPTO_AUTH_SHA512_HMAC: + ret = (mac_len == 64) ? 0 : -1; + break; + case RTE_CRYPTO_AUTH_NULL: + ret = 0; + break; + default: + ret = -1; + } + + return ret; +} + + static __rte_always_inline int fill_sess_cipher(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess) { @@ -134,4 +176,156 @@ fill_sess_cipher(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess) return 0; } + +static __rte_always_inline int +fill_sess_auth(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess) +{ + struct rte_crypto_auth_xform *a_form; + roc_se_auth_type auth_type = 0; /* NULL Auth type */ + uint8_t zsk_flag = 0, aes_gcm = 0, is_null = 0; + + if (xform->next != NULL && + xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER && + xform->next->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) { + /* Perform auth followed by encryption */ + sess->roc_se_ctx.template_w4.s.opcode_minor = + ROC_SE_FC_MINOR_OP_HMAC_FIRST; + } + + a_form = &xform->auth; + + if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY) + sess->cpt_op |= ROC_SE_OP_AUTH_VERIFY; + else if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE) + sess->cpt_op |= ROC_SE_OP_AUTH_GENERATE; + else { + plt_dp_err("Unknown auth operation"); + return -1; + } + + switch (a_form->algo) { + case RTE_CRYPTO_AUTH_SHA1_HMAC: + /* Fall through */ + case RTE_CRYPTO_AUTH_SHA1: + auth_type = ROC_SE_SHA1_TYPE; + break; + case RTE_CRYPTO_AUTH_SHA256_HMAC: + case RTE_CRYPTO_AUTH_SHA256: + auth_type = ROC_SE_SHA2_SHA256; + break; + case RTE_CRYPTO_AUTH_SHA512_HMAC: + case RTE_CRYPTO_AUTH_SHA512: + auth_type = ROC_SE_SHA2_SHA512; + break; + case RTE_CRYPTO_AUTH_AES_GMAC: + auth_type = ROC_SE_GMAC_TYPE; + aes_gcm = 1; + break; + case RTE_CRYPTO_AUTH_SHA224_HMAC: + case RTE_CRYPTO_AUTH_SHA224: + auth_type = ROC_SE_SHA2_SHA224; + break; + case RTE_CRYPTO_AUTH_SHA384_HMAC: + case RTE_CRYPTO_AUTH_SHA384: + auth_type = ROC_SE_SHA2_SHA384; + break; + case RTE_CRYPTO_AUTH_MD5_HMAC: + case RTE_CRYPTO_AUTH_MD5: + auth_type = ROC_SE_MD5_TYPE; + break; + case RTE_CRYPTO_AUTH_KASUMI_F9: + auth_type = ROC_SE_KASUMI_F9_ECB; + /* + * Indicate that direction needs to be taken out + * from end of src + */ + zsk_flag = ROC_SE_K_F9; + break; + case RTE_CRYPTO_AUTH_SNOW3G_UIA2: + auth_type = ROC_SE_SNOW3G_UIA2; + zsk_flag = ROC_SE_ZS_IA; + break; + case RTE_CRYPTO_AUTH_ZUC_EIA3: + auth_type = ROC_SE_ZUC_EIA3; + zsk_flag = ROC_SE_ZS_IA; + break; + case RTE_CRYPTO_AUTH_NULL: + auth_type = 0; + is_null = 1; + break; + case RTE_CRYPTO_AUTH_AES_XCBC_MAC: + case RTE_CRYPTO_AUTH_AES_CMAC: + case RTE_CRYPTO_AUTH_AES_CBC_MAC: + plt_dp_err("Crypto: Unsupported hash algo %u", a_form->algo); + return -1; + default: + plt_dp_err("Crypto: Undefined Hash algo %u specified", + a_form->algo); + return -1; + } + + sess->zsk_flag = zsk_flag; + sess->aes_gcm = aes_gcm; + sess->mac_len = a_form->digest_length; + sess->is_null = is_null; + if (zsk_flag) { + sess->auth_iv_offset = a_form->iv.offset; + sess->auth_iv_length = a_form->iv.length; + } + if (unlikely(roc_se_auth_key_set(&sess->roc_se_ctx, auth_type, + a_form->key.data, a_form->key.length, + a_form->digest_length))) + return -1; + + return 0; +} + +static __rte_always_inline int +fill_sess_gmac(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess) +{ + struct rte_crypto_auth_xform *a_form; + roc_se_cipher_type enc_type = 0; /* NULL Cipher type */ + roc_se_auth_type auth_type = 0; /* NULL Auth type */ + + a_form = &xform->auth; + + if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE) + sess->cpt_op |= ROC_SE_OP_ENCODE; + else if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY) + sess->cpt_op |= ROC_SE_OP_DECODE; + else { + plt_dp_err("Unknown auth operation"); + return -1; + } + + switch (a_form->algo) { + case RTE_CRYPTO_AUTH_AES_GMAC: + enc_type = ROC_SE_AES_GCM; + auth_type = ROC_SE_GMAC_TYPE; + break; + default: + plt_dp_err("Crypto: Undefined cipher algo %u specified", + a_form->algo); + return -1; + } + + sess->zsk_flag = 0; + sess->aes_gcm = 0; + sess->is_gmac = 1; + sess->iv_offset = a_form->iv.offset; + sess->iv_length = a_form->iv.length; + sess->mac_len = a_form->digest_length; + + if (unlikely(roc_se_ciph_key_set(&sess->roc_se_ctx, enc_type, + a_form->key.data, a_form->key.length, + NULL))) + return -1; + + if (unlikely(roc_se_auth_key_set(&sess->roc_se_ctx, auth_type, NULL, 0, + a_form->digest_length))) + return -1; + + return 0; +} + #endif /*_CNXK_SE_H_ */ -- 2.20.1