@@ -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)
@@ -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);
+ }
+}
@@ -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