From: Ragothaman Jayaraman <ragothaman.jayara...@cavium.com> This patch adds the session callbacks functions. The cipher keys, auth keys and aead keys are set during the session configure.
Signed-off-by: Ankur Dwivedi <ankur.dwiv...@cavium.com> Signed-off-by: Murthy NSSR <nidadavolu.mur...@cavium.com> Signed-off-by: Nithin Dabilpuram <nithin.dabilpu...@cavium.com> Signed-off-by: Ragothaman Jayaraman <ragothaman.jayara...@cavium.com> Signed-off-by: Srisivasubramanian Srinivasan <srisivasubramanian.sriniva...@cavium.com> --- drivers/crypto/cpt/cpt_pmd_cryptodev.c | 6 +- drivers/crypto/cpt/cpt_pmd_ops.c | 470 +++++++++++++++++++++++++++++++++ drivers/crypto/cpt/cpt_pmd_ops.h | 11 + 3 files changed, 484 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/cpt/cpt_pmd_cryptodev.c b/drivers/crypto/cpt/cpt_pmd_cryptodev.c index 3961ec8..939f31b 100644 --- a/drivers/crypto/cpt/cpt_pmd_cryptodev.c +++ b/drivers/crypto/cpt/cpt_pmd_cryptodev.c @@ -62,9 +62,9 @@ .queue_pair_count = NULL, /* Crypto related operations */ - .session_get_size = NULL, - .session_configure = NULL, - .session_clear = NULL + .session_get_size = cpt_pmd_get_session_size, + .session_configure = cpt_pmd_session_cfg, + .session_clear = cpt_pmd_session_clear }; static int init_global_resources(void) diff --git a/drivers/crypto/cpt/cpt_pmd_ops.c b/drivers/crypto/cpt/cpt_pmd_ops.c index 1c60191..37808ce 100644 --- a/drivers/crypto/cpt/cpt_pmd_ops.c +++ b/drivers/crypto/cpt/cpt_pmd_ops.c @@ -605,3 +605,473 @@ void cpt_pmd_stats_reset(struct rte_cryptodev *dev __rte_unused) return 0; } + +unsigned int +cpt_pmd_get_session_size(struct rte_cryptodev *dev __rte_unused) +{ + return (sizeof(struct cpt_sess_misc) + + RTE_ALIGN_CEIL(cpt_fc_get_ctx_len(), 8)); +} + +static int +fill_sess_aead(cpt_instance_t *instance, struct rte_crypto_sym_xform *xform, + struct cpt_sess_misc *sess) +{ + struct rte_crypto_aead_xform *aead_form; + cipher_type_t enc_type = 0; /* NULL Cipher type */ + auth_type_t auth_type = 0; /* NULL Auth type */ + uint32_t cipher_key_len = 0; + uint8_t zsk_flag = 0, aes_gcm = 0; + aead_form = &xform->aead; + if (aead_form->op == RTE_CRYPTO_AEAD_OP_ENCRYPT && + aead_form->algo == RTE_CRYPTO_AEAD_AES_GCM) { + sess->cpt_op |= CSP_OP_CIPHER_ENCRYPT; + sess->cpt_op |= CSP_OP_AUTH_GENERATE; + } else if (aead_form->op == RTE_CRYPTO_AEAD_OP_DECRYPT && + aead_form->algo == RTE_CRYPTO_AEAD_AES_GCM) { + sess->cpt_op |= CSP_OP_CIPHER_DECRYPT; + sess->cpt_op |= CSP_OP_AUTH_VERIFY; + } else { + PMD_DRV_LOG(ERR, "Unknown cipher operation\n"); + return -1; + } + if (aead_form->key.length < cipher_key_len) { + PMD_DRV_LOG(ERR, "Invalid cipher params keylen %lu\n", + (unsigned int long)aead_form->key.length); + return -1; + } + switch (aead_form->algo) { + case RTE_CRYPTO_AEAD_AES_GCM: + enc_type = AES_GCM; + cipher_key_len = 16; + aes_gcm = 1; + break; + case RTE_CRYPTO_AEAD_AES_CCM: + PMD_DRV_LOG(ERR, "Crypto: Unsupported cipher alg %u", + aead_form->algo); + return -1; + default: + PMD_DRV_LOG(ERR, "Crypto: Undefined cipher algo %u specified", + aead_form->algo); + return -1; + } + sess->zsk_flag = zsk_flag; + sess->aes_gcm = aes_gcm; + sess->mac_len = aead_form->digest_length; + sess->iv_offset = aead_form->iv.offset; + sess->iv_length = aead_form->iv.length; + sess->aad_length = aead_form->aad_length; + cpt_fc_ciph_set_key(instance, + (void *)((uint8_t *)sess + sizeof(struct cpt_sess_misc)), + enc_type, + aead_form->key.data, + aead_form->key.length, + NULL); + + cpt_fc_auth_set_key(instance, + (void *)((uint8_t *)sess + sizeof(struct cpt_sess_misc)), + auth_type, + NULL, + 0, + aead_form->digest_length); + + return 0; +} +static int +fill_sess_cipher(cpt_instance_t *instance, struct rte_crypto_sym_xform *xform, + struct cpt_sess_misc *sess) +{ + struct rte_crypto_cipher_xform *c_form; + cipher_type_t enc_type = 0; /* NULL Cipher type */ + uint32_t cipher_key_len = 0; + uint8_t zsk_flag = 0, aes_gcm = 0, aes_ctr = 0; + + if (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER) + return -1; + + c_form = &xform->cipher; + + if (c_form->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) + sess->cpt_op |= CSP_OP_CIPHER_ENCRYPT; + else if (c_form->op == RTE_CRYPTO_CIPHER_OP_DECRYPT) + sess->cpt_op |= CSP_OP_CIPHER_DECRYPT; + else { + PMD_DRV_LOG(ERR, "Unknown cipher operation\n"); + return -1; + } + + switch (c_form->algo) { + case RTE_CRYPTO_CIPHER_AES_CBC: + enc_type = AES_CBC; + cipher_key_len = 16; + sess->dir_dma_supp |= CSP_DDMA_ENC; + break; + case RTE_CRYPTO_CIPHER_3DES_CBC: + enc_type = DES3_CBC; + cipher_key_len = 24; + break; + case RTE_CRYPTO_CIPHER_AES_CTR: + enc_type = AES_CTR; + cipher_key_len = 16; + aes_ctr = 1; + break; + case RTE_CRYPTO_CIPHER_NULL: + enc_type = 0; + break; + case RTE_CRYPTO_CIPHER_KASUMI_F8: + enc_type = KASUMI_F8_ECB; + cipher_key_len = 16; + zsk_flag = K_F8; + break; + case RTE_CRYPTO_CIPHER_SNOW3G_UEA2: + enc_type = SNOW3G_UEA2; + cipher_key_len = 16; + zsk_flag = ZS_EA; + break; + case RTE_CRYPTO_CIPHER_ZUC_EEA3: + enc_type = ZUC_EEA3; + cipher_key_len = 16; + zsk_flag = ZS_EA; + break; + case RTE_CRYPTO_CIPHER_AES_XTS: + enc_type = AES_XTS; + cipher_key_len = 16; + break; + case RTE_CRYPTO_CIPHER_3DES_ECB: + enc_type = DES3_ECB; + cipher_key_len = 24; + break; + case RTE_CRYPTO_CIPHER_AES_ECB: + enc_type = AES_ECB; + cipher_key_len = 16; + break; + case RTE_CRYPTO_CIPHER_3DES_CTR: + case RTE_CRYPTO_CIPHER_AES_F8: + case RTE_CRYPTO_CIPHER_ARC4: + PMD_DRV_LOG(ERR, "Crypto: Unsupported cipher alg %u", + c_form->algo); + return -1; + default: + PMD_DRV_LOG(ERR, "Crypto: Undefined cipher algo %u specified", + c_form->algo); + return -1; + } + + if (c_form->key.length < cipher_key_len) { + PMD_DRV_LOG(ERR, "Invalid cipher params keylen %lu\n", + (unsigned long) c_form->key.length); + return -1; + } + + sess->zsk_flag = zsk_flag; + sess->aes_gcm = aes_gcm; + sess->aes_ctr = aes_ctr; + sess->iv_offset = c_form->iv.offset; + sess->iv_length = c_form->iv.length; + cpt_fc_ciph_set_key(instance, + SESS_PRIV(sess), + enc_type, + c_form->key.data, + c_form->key.length, + NULL); + + return 0; +} + +static int +fill_sess_auth(cpt_instance_t *instance, struct rte_crypto_sym_xform *xform, + struct cpt_sess_misc *sess) +{ + struct rte_crypto_auth_xform *a_form; + auth_type_t auth_type = 0; /* NULL Auth type */ + uint8_t zsk_flag = 0, aes_gcm = 0; + + if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH) + goto error_out; + + a_form = &xform->auth; + + if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY) + sess->cpt_op |= CSP_OP_AUTH_VERIFY; + else if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE) + sess->cpt_op |= CSP_OP_AUTH_GENERATE; + else { + PMD_DRV_LOG(ERR, "Unknown auth operation\n"); + return -1; + } + + if (a_form->key.length > 64) { + PMD_DRV_LOG(ERR, "Auth key length is big\n"); + return -1; + } + + switch (a_form->algo) { + case RTE_CRYPTO_AUTH_SHA1_HMAC: + sess->dir_dma_supp |= CSP_DDMA_AUTH; + /* Fall through */ + case RTE_CRYPTO_AUTH_SHA1: + auth_type = SHA1_TYPE; + break; + case RTE_CRYPTO_AUTH_SHA256_HMAC: + case RTE_CRYPTO_AUTH_SHA256: + auth_type = SHA2_SHA256; + break; + case RTE_CRYPTO_AUTH_SHA512_HMAC: + case RTE_CRYPTO_AUTH_SHA512: + auth_type = SHA2_SHA512; + break; + case RTE_CRYPTO_AUTH_AES_GMAC: + auth_type = GMAC_TYPE; + aes_gcm = 1; + break; + case RTE_CRYPTO_AUTH_SHA224_HMAC: + case RTE_CRYPTO_AUTH_SHA224: + auth_type = SHA2_SHA224; + break; + case RTE_CRYPTO_AUTH_SHA384_HMAC: + case RTE_CRYPTO_AUTH_SHA384: + auth_type = SHA2_SHA384; + break; + case RTE_CRYPTO_AUTH_MD5_HMAC: + case RTE_CRYPTO_AUTH_MD5: + auth_type = MD5_TYPE; + break; + case RTE_CRYPTO_AUTH_KASUMI_F9: + auth_type = KASUMI_F9_ECB; + /* + * Indicate that direction needs to be taken out + * from end of src + */ + zsk_flag = K_F9; + break; + case RTE_CRYPTO_AUTH_SNOW3G_UIA2: + auth_type = SNOW3G_UIA2; + zsk_flag = ZS_IA; + break; + case RTE_CRYPTO_AUTH_ZUC_EIA3: + auth_type = ZUC_EIA3; + zsk_flag = ZS_IA; + break; + case RTE_CRYPTO_AUTH_AES_XCBC_MAC: + case RTE_CRYPTO_AUTH_AES_CMAC: + case RTE_CRYPTO_AUTH_AES_CBC_MAC: + case RTE_CRYPTO_AUTH_NULL: + PMD_DRV_LOG(ERR, "Crypto: Unsupported hash alg %u", + a_form->algo); + goto error_out; + default: + PMD_DRV_LOG(ERR, "Crypto: Undefined Hash algo %u specified", + a_form->algo); + goto error_out; + } + + sess->zsk_flag = zsk_flag; + sess->aes_gcm = aes_gcm; + sess->mac_len = a_form->digest_length; + if (zsk_flag) { + sess->auth_iv_offset = a_form->iv.offset; + sess->auth_iv_length = a_form->iv.length; + } + cpt_fc_auth_set_key(instance, + SESS_PRIV(sess), + auth_type, + a_form->key.data, + a_form->key.length, + a_form->digest_length); + + return 0; + +error_out: + return -1; +} +static int +fill_sess_gmac(cpt_instance_t *instance, struct rte_crypto_sym_xform *xform, + struct cpt_sess_misc *sess) +{ + struct rte_crypto_auth_xform *a_form; + cipher_type_t enc_type = 0; /* NULL Cipher type */ + auth_type_t auth_type = 0; /* NULL Auth type */ + uint8_t zsk_flag = 0, aes_gcm = 0; + + if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH) + return -1; + + a_form = &xform->auth; + + if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE) + sess->cpt_op |= CSP_OP_ENCODE; + else if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY) + sess->cpt_op |= CSP_OP_DECODE; + else { + PMD_DRV_LOG(ERR, "Unknown auth operation\n"); + return -1; + } + + switch (a_form->algo) { + case RTE_CRYPTO_AUTH_AES_GMAC: + enc_type = AES_GCM; + auth_type = GMAC_TYPE; + break; + default: + PMD_DRV_LOG(ERR, "Crypto: Undefined cipher algo %u specified", + a_form->algo); + return -1; + } + + sess->zsk_flag = zsk_flag; + sess->aes_gcm = aes_gcm; + 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; + cpt_fc_ciph_set_key(instance, + (void *)((uint8_t *)sess + sizeof(struct cpt_sess_misc)), + enc_type, + a_form->key.data, + a_form->key.length, + NULL); + cpt_fc_auth_set_key(instance, + (void *)((uint8_t *)sess + sizeof(struct cpt_sess_misc)), + auth_type, + NULL, + 0, + a_form->digest_length); + + return 0; +} + +static void +cpt_pmd_session_init(struct rte_mempool *mp __rte_unused, void *sym_sess, + uint8_t driver_id) +{ + struct rte_cryptodev_sym_session *sess = sym_sess; + struct cpt_sess_misc *cpt_sess = + (struct cpt_sess_misc *) get_session_private_data(sess, driver_id); + + PMD_INIT_FUNC_TRACE(); + cpt_sess->ctx_dma_addr = rte_mempool_virt2iova(cpt_sess) + + sizeof(struct cpt_sess_misc); +} + + +int cpt_pmd_session_cfg(struct rte_cryptodev *dev, + struct rte_crypto_sym_xform *xform, + struct rte_cryptodev_sym_session *sess, + struct rte_mempool *mempool) +{ + struct rte_crypto_sym_xform *chain; + void *sess_private_data; + + PMD_INIT_FUNC_TRACE(); + + /* + * Microcode only supports the following combination. + * Encryption followed by authentication + * Authentication followed by decryption + * Also zuc, kasumi and snow3g are not supported in + * aead mode(ie. cipher+auth), but only cipher or auth. + */ + if (xform->next) { + if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) { + if ((xform->auth.algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2) || + (xform->auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3) || + (xform->auth.algo == RTE_CRYPTO_AUTH_KASUMI_F9)) { + PMD_DRV_LOG(ERR, "Requested auth algorithm in " + "combination with cipher unsupported\n"); + goto err; + } + if ((xform->next->type == + RTE_CRYPTO_SYM_XFORM_CIPHER) && + (xform->next->cipher.op == + RTE_CRYPTO_CIPHER_OP_ENCRYPT)) { + PMD_DRV_LOG(ERR, "Unsupported combination by " + "microcode\n"); + goto err; + /* Unsupported as of now by microcode */ + } + } + if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { + if ((xform->cipher.algo == + RTE_CRYPTO_CIPHER_SNOW3G_UEA2) || + (xform->cipher.algo == + RTE_CRYPTO_CIPHER_ZUC_EEA3) || + (xform->cipher.algo == + RTE_CRYPTO_CIPHER_KASUMI_F8)) { + PMD_DRV_LOG(ERR, "Requested cipher algorithm " + "in combination with auth unsupported\n"); + goto err; + } + if ((xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) && + (xform->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT)) { + /* For GMAC auth there is no cipher operation */ + if ((xform->aead.algo != + RTE_CRYPTO_AEAD_AES_GCM) || + (xform->next->auth.algo != + RTE_CRYPTO_AUTH_AES_GMAC)) { + PMD_DRV_LOG(ERR, "Unsupported " + "combination by microcode\n"); + goto err; + /* Unsupported as of now by microcode */ + } + } + } + } + + if (unlikely(sess == NULL)) { + PMD_DRV_LOG(ERR, "invalid session struct"); + return -EINVAL; + } + + if (rte_mempool_get(mempool, &sess_private_data)) { + PMD_DRV_LOG(ERR, "Could not allocate sess_private_data\n"); + return -ENOMEM; + } + + chain = xform; + ((struct cpt_sess_misc *) sess_private_data)->dir_dma_supp = 0; + /* TODO: Need to restrict this loop to 2 chain elements? */ + while (chain) { + if (chain->type == RTE_CRYPTO_SYM_XFORM_AEAD) { + if (fill_sess_aead(NULL, chain, sess_private_data)) + goto err; + } else { + if (chain->type == RTE_CRYPTO_SYM_XFORM_CIPHER) { + if (fill_sess_cipher(NULL, chain, sess_private_data)) + goto err; + } else if (chain->type == RTE_CRYPTO_SYM_XFORM_AUTH) { + if (chain->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) { + if (fill_sess_gmac(NULL, chain, + sess_private_data)) + goto err; + } else { + if (fill_sess_auth(NULL, chain, sess_private_data)) + goto err; + } + } + } + chain = chain->next; + } + set_session_private_data(sess, dev->driver_id, sess_private_data); + cpt_pmd_session_init(NULL, sess, dev->driver_id); + return 0; + +err: + /* TODO: rte_mempool_put(); */ + return -EPERM; +} + +void +cpt_pmd_session_clear(struct rte_cryptodev *dev, + struct rte_cryptodev_sym_session *sess) +{ + void *session_private = get_session_private_data(sess, dev->driver_id); + + PMD_INIT_FUNC_TRACE(); + if (session_private) { + memset(session_private, 0, cpt_pmd_get_session_size(dev)); + struct rte_mempool *sess_mp = + rte_mempool_from_obj(session_private); + set_session_private_data(sess, dev->driver_id, NULL); + rte_mempool_put(sess_mp, session_private); + } +} diff --git a/drivers/crypto/cpt/cpt_pmd_ops.h b/drivers/crypto/cpt/cpt_pmd_ops.h index db2024b..314b2b1 100644 --- a/drivers/crypto/cpt/cpt_pmd_ops.h +++ b/drivers/crypto/cpt/cpt_pmd_ops.h @@ -72,4 +72,15 @@ void cpt_pmd_stats_get(struct rte_cryptodev *dev, void cpt_pmd_stats_reset(struct rte_cryptodev *dev); +unsigned int +cpt_pmd_get_session_size(struct rte_cryptodev *dev); + +int cpt_pmd_session_cfg(struct rte_cryptodev *dev, + struct rte_crypto_sym_xform *xform, + struct rte_cryptodev_sym_session *sess, + struct rte_mempool *mempool); + +void +cpt_pmd_session_clear(struct rte_cryptodev *dev, + struct rte_cryptodev_sym_session *sess); #endif -- 1.9.3