X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_cryptodev%2Frte_cryptodev.c;h=9ea4ece65e6e780688a6759ca13422bad0ef3059;hb=53bf0ffd51c0b378246aac74308cc0ceaf075f83;hp=410520f991a152595e8c2c02d392722a82375707;hpb=6c9f3b347e21510aa46251d69ab4c809b3ec1261;p=dpdk.git diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c index 410520f991..9ea4ece65e 100644 --- a/lib/librte_cryptodev/rte_cryptodev.c +++ b/lib/librte_cryptodev/rte_cryptodev.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2015-2017 Intel Corporation + * Copyright(c) 2015-2020 Intel Corporation */ #include @@ -36,10 +36,13 @@ #include #include #include +#include +#include #include "rte_crypto.h" #include "rte_cryptodev.h" #include "rte_cryptodev_pmd.h" +#include "rte_cryptodev_trace.h" static uint8_t nb_drivers; @@ -56,6 +59,14 @@ static struct rte_cryptodev_global cryptodev_globals = { /* spinlock for crypto device callbacks */ static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER; +static const struct rte_cryptodev_capabilities + cryptodev_undefined_capabilities[] = { + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST() +}; + +static struct rte_cryptodev_capabilities + *capability_copy[RTE_CRYPTO_MAX_DEVS]; +static uint8_t is_capability_checked[RTE_CRYPTO_MAX_DEVS]; /** * The user application callback description. @@ -174,6 +185,8 @@ const char *rte_crypto_asym_xform_strings[] = { [RTE_CRYPTO_ASYM_XFORM_MODINV] = "modinv", [RTE_CRYPTO_ASYM_XFORM_DH] = "dh", [RTE_CRYPTO_ASYM_XFORM_DSA] = "dsa", + [RTE_CRYPTO_ASYM_XFORM_ECDSA] = "ecdsa", + [RTE_CRYPTO_ASYM_XFORM_ECPM] = "ecpm", }; /** @@ -278,15 +291,15 @@ rte_crypto_auth_operation_strings[] = { [RTE_CRYPTO_AUTH_OP_GENERATE] = "generate" }; -const struct rte_cryptodev_symmetric_capability * -rte_cryptodev_sym_capability_get(uint8_t dev_id, +const struct rte_cryptodev_symmetric_capability __vsym * +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id, const struct rte_cryptodev_sym_capability_idx *idx) { const struct rte_cryptodev_capabilities *capability; struct rte_cryptodev_info dev_info; int i = 0; - rte_cryptodev_info_get(dev_id, &dev_info); + rte_cryptodev_info_get_v20(dev_id, &dev_info); while ((capability = &dev_info.capabilities[i++])->op != RTE_CRYPTO_OP_TYPE_UNDEFINED) { @@ -310,8 +323,47 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id, } return NULL; +} +VERSION_SYMBOL(rte_cryptodev_sym_capability_get, _v20, 20.0); + +const struct rte_cryptodev_symmetric_capability __vsym * +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id, + const struct rte_cryptodev_sym_capability_idx *idx) +{ + const struct rte_cryptodev_capabilities *capability; + struct rte_cryptodev_info dev_info; + int i = 0; + + rte_cryptodev_info_get(dev_id, &dev_info); + + while ((capability = &dev_info.capabilities[i++])->op != + RTE_CRYPTO_OP_TYPE_UNDEFINED) { + if (capability->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC) + continue; + + if (capability->sym.xform_type != idx->type) + continue; + + if (idx->type == RTE_CRYPTO_SYM_XFORM_AUTH && + capability->sym.auth.algo == idx->algo.auth) + return &capability->sym; + + if (idx->type == RTE_CRYPTO_SYM_XFORM_CIPHER && + capability->sym.cipher.algo == idx->algo.cipher) + return &capability->sym; + if (idx->type == RTE_CRYPTO_SYM_XFORM_AEAD && + capability->sym.aead.algo == idx->algo.aead) + return &capability->sym; + } + + return NULL; } +MAP_STATIC_SYMBOL(const struct rte_cryptodev_symmetric_capability * + rte_cryptodev_sym_capability_get(uint8_t dev_id, + const struct rte_cryptodev_sym_capability_idx *idx), + rte_cryptodev_sym_capability_get_v21); +BIND_DEFAULT_SYMBOL(rte_cryptodev_sym_capability_get, _v21, 21); static int param_range_check(uint16_t size, const struct rte_crypto_param_range *range) @@ -492,6 +544,14 @@ rte_cryptodev_get_feature_name(uint64_t flag) return "RSA_PRIV_OP_KEY_QT"; case RTE_CRYPTODEV_FF_DIGEST_ENCRYPTED: return "DIGEST_ENCRYPTED"; + case RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO: + return "SYM_CPU_CRYPTO"; + case RTE_CRYPTODEV_FF_ASYM_SESSIONLESS: + return "ASYM_SESSIONLESS"; + case RTE_CRYPTODEV_FF_SYM_SESSIONLESS: + return "SYM_SESSIONLESS"; + case RTE_CRYPTODEV_FF_NON_BYTE_ALIGNED_DATA: + return "NON_BYTE_ALIGNED_DATA"; default: return NULL; } @@ -526,7 +586,8 @@ rte_cryptodev_pmd_get_named_dev(const char *name) static inline uint8_t rte_cryptodev_is_valid_device_data(uint8_t dev_id) { - if (rte_crypto_devices[dev_id].data == NULL) + if (dev_id >= RTE_CRYPTO_MAX_DEVS || + rte_crypto_devices[dev_id].data == NULL) return 0; return 1; @@ -618,8 +679,9 @@ rte_cryptodev_devices_get(const char *driver_name, uint8_t *devices, void * rte_cryptodev_get_sec_ctx(uint8_t dev_id) { - if (rte_crypto_devices[dev_id].feature_flags & - RTE_CRYPTODEV_FF_SECURITY) + if (dev_id < RTE_CRYPTO_MAX_DEVS && + (rte_crypto_devices[dev_id].feature_flags & + RTE_CRYPTODEV_FF_SECURITY)) return rte_crypto_devices[dev_id].security_ctx; return NULL; @@ -790,6 +852,11 @@ rte_cryptodev_queue_pair_count(uint8_t dev_id) { struct rte_cryptodev *dev; + if (!rte_cryptodev_is_valid_device_data(dev_id)) { + CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id); + return 0; + } + dev = &rte_crypto_devices[dev_id]; return dev->data->nb_queue_pairs; } @@ -902,6 +969,7 @@ rte_cryptodev_configure(uint8_t dev_id, struct rte_cryptodev_config *config) return diag; } + rte_cryptodev_trace_configure(dev_id, config); return (*dev->dev_ops->dev_configure)(dev, config); } @@ -930,6 +998,7 @@ rte_cryptodev_start(uint8_t dev_id) } diag = (*dev->dev_ops->dev_start)(dev); + rte_cryptodev_trace_start(dev_id, diag); if (diag == 0) dev->data->dev_started = 1; else @@ -959,6 +1028,7 @@ rte_cryptodev_stop(uint8_t dev_id) } (*dev->dev_ops->dev_stop)(dev); + rte_cryptodev_trace_stop(dev_id); dev->data->dev_started = 0; } @@ -995,6 +1065,13 @@ rte_cryptodev_close(uint8_t dev_id) RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP); retval = (*dev->dev_ops->dev_close)(dev); + rte_cryptodev_trace_close(dev_id, retval); + + if (capability_copy[dev_id]) { + free(capability_copy[dev_id]); + capability_copy[dev_id] = NULL; + } + is_capability_checked[dev_id] = 0; if (retval < 0) return retval; @@ -1064,6 +1141,7 @@ rte_cryptodev_queue_pair_setup(uint8_t dev_id, uint16_t queue_pair_id, RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->queue_pair_setup, -ENOTSUP); + rte_cryptodev_trace_queue_pair_setup(dev_id, queue_pair_id, qp_conf); return (*dev->dev_ops->queue_pair_setup)(dev, queue_pair_id, qp_conf, socket_id); } @@ -1108,9 +1186,61 @@ rte_cryptodev_stats_reset(uint8_t dev_id) (*dev->dev_ops->stats_reset)(dev); } +static void +get_v20_capabilities(uint8_t dev_id, struct rte_cryptodev_info *dev_info) +{ + const struct rte_cryptodev_capabilities *capability; + uint8_t found_invalid_capa = 0; + uint8_t counter = 0; + + for (capability = dev_info->capabilities; + capability->op != RTE_CRYPTO_OP_TYPE_UNDEFINED; + ++capability, ++counter) { + if (capability->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC && + capability->sym.xform_type == + RTE_CRYPTO_SYM_XFORM_AEAD + && capability->sym.aead.algo >= + RTE_CRYPTO_AEAD_CHACHA20_POLY1305) { + found_invalid_capa = 1; + counter--; + } + } + is_capability_checked[dev_id] = 1; + if (!found_invalid_capa) + return; + capability_copy[dev_id] = malloc(counter * + sizeof(struct rte_cryptodev_capabilities)); + if (capability_copy[dev_id] == NULL) { + /* + * error case - no memory to store the trimmed + * list, so have to return an empty list + */ + dev_info->capabilities = + cryptodev_undefined_capabilities; + is_capability_checked[dev_id] = 0; + } else { + counter = 0; + for (capability = dev_info->capabilities; + capability->op != + RTE_CRYPTO_OP_TYPE_UNDEFINED; + capability++) { + if (!(capability->op == + RTE_CRYPTO_OP_TYPE_SYMMETRIC + && capability->sym.xform_type == + RTE_CRYPTO_SYM_XFORM_AEAD + && capability->sym.aead.algo >= + RTE_CRYPTO_AEAD_CHACHA20_POLY1305)) { + capability_copy[dev_id][counter++] = + *capability; + } + } + dev_info->capabilities = + capability_copy[dev_id]; + } +} -void -rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info) +void __vsym +rte_cryptodev_info_get_v20(uint8_t dev_id, struct rte_cryptodev_info *dev_info) { struct rte_cryptodev *dev; @@ -1126,10 +1256,40 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info) RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get); (*dev->dev_ops->dev_infos_get)(dev, dev_info); + if (capability_copy[dev_id] == NULL) { + if (!is_capability_checked[dev_id]) + get_v20_capabilities(dev_id, dev_info); + } else + dev_info->capabilities = capability_copy[dev_id]; + dev_info->driver_name = dev->device->driver->name; dev_info->device = dev->device; } +VERSION_SYMBOL(rte_cryptodev_info_get, _v20, 20.0); +void __vsym +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info *dev_info) +{ + struct rte_cryptodev *dev; + + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) { + CDEV_LOG_ERR("Invalid dev_id=%d", dev_id); + return; + } + + dev = &rte_crypto_devices[dev_id]; + + memset(dev_info, 0, sizeof(struct rte_cryptodev_info)); + + RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get); + (*dev->dev_ops->dev_infos_get)(dev, dev_info); + + dev_info->driver_name = dev->device->driver->name; + dev_info->device = dev->device; +} +MAP_STATIC_SYMBOL(void rte_cryptodev_info_get(uint8_t dev_id, + struct rte_cryptodev_info *dev_info), rte_cryptodev_info_get_v21); +BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v21, 21); int rte_cryptodev_callback_register(uint8_t dev_id, @@ -1255,9 +1415,14 @@ rte_cryptodev_sym_session_init(uint8_t dev_id, uint8_t index; int ret; + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) { + CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id); + return -EINVAL; + } + dev = rte_cryptodev_pmd_get_dev(dev_id); - if (sess == NULL || xforms == NULL || dev == NULL) + if (sess == NULL || xforms == NULL || dev == NULL || mp == NULL) return -EINVAL; if (mp->elt_size < sess_priv_sz) @@ -1280,6 +1445,7 @@ rte_cryptodev_sym_session_init(uint8_t dev_id, } } + rte_cryptodev_trace_sym_session_init(dev_id, sess, xforms, mp); sess->sess_data[index].refcnt++; return 0; } @@ -1294,6 +1460,11 @@ rte_cryptodev_asym_session_init(uint8_t dev_id, uint8_t index; int ret; + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) { + CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id); + return -EINVAL; + } + dev = rte_cryptodev_pmd_get_dev(dev_id); if (sess == NULL || xforms == NULL || dev == NULL) @@ -1316,6 +1487,7 @@ rte_cryptodev_asym_session_init(uint8_t dev_id, } } + rte_cryptodev_trace_asym_session_init(dev_id, sess, xforms, mp); return 0; } @@ -1356,6 +1528,8 @@ rte_cryptodev_sym_session_pool_create(const char *name, uint32_t nb_elts, pool_priv->nb_drivers = nb_drivers; pool_priv->user_data_sz = user_data_size; + rte_cryptodev_trace_sym_session_pool_create(name, nb_elts, + elt_size, cache_size, user_data_size, mp); return mp; } @@ -1366,24 +1540,39 @@ rte_cryptodev_sym_session_data_size(struct rte_cryptodev_sym_session *sess) sess->user_data_sz; } +static uint8_t +rte_cryptodev_sym_is_valid_session_pool(struct rte_mempool *mp) +{ + struct rte_cryptodev_sym_session_pool_private_data *pool_priv; + + if (!mp) + return 0; + + pool_priv = rte_mempool_get_priv(mp); + + if (!pool_priv || mp->private_data_size < sizeof(*pool_priv) || + pool_priv->nb_drivers != nb_drivers || + mp->elt_size < + rte_cryptodev_sym_get_header_session_size() + + pool_priv->user_data_sz) + return 0; + + return 1; +} + struct rte_cryptodev_sym_session * rte_cryptodev_sym_session_create(struct rte_mempool *mp) { struct rte_cryptodev_sym_session *sess; struct rte_cryptodev_sym_session_pool_private_data *pool_priv; - if (!mp) { + if (!rte_cryptodev_sym_is_valid_session_pool(mp)) { CDEV_LOG_ERR("Invalid mempool\n"); return NULL; } pool_priv = rte_mempool_get_priv(mp); - if (!pool_priv || mp->private_data_size < sizeof(*pool_priv)) { - CDEV_LOG_ERR("Invalid mempool\n"); - return NULL; - } - /* Allocate a session structure from the session pool */ if (rte_mempool_get(mp, (void **)&sess)) { CDEV_LOG_ERR("couldn't get object from session mempool"); @@ -1400,6 +1589,7 @@ rte_cryptodev_sym_session_create(struct rte_mempool *mp) memset(sess->sess_data, 0, rte_cryptodev_sym_session_data_size(sess)); + rte_cryptodev_trace_sym_session_create(mp, sess); return sess; } @@ -1407,6 +1597,20 @@ struct rte_cryptodev_asym_session * rte_cryptodev_asym_session_create(struct rte_mempool *mp) { struct rte_cryptodev_asym_session *sess; + unsigned int session_size = + rte_cryptodev_asym_get_header_session_size(); + + if (!mp) { + CDEV_LOG_ERR("invalid mempool\n"); + return NULL; + } + + /* Verify if provided mempool can hold elements big enough. */ + if (mp->elt_size < session_size) { + CDEV_LOG_ERR( + "mempool elements too small to hold session objects"); + return NULL; + } /* Allocate a session structure from the session pool */ if (rte_mempool_get(mp, (void **)&sess)) { @@ -1417,8 +1621,9 @@ rte_cryptodev_asym_session_create(struct rte_mempool *mp) /* Clear device session pointer. * Include the flag indicating presence of private data */ - memset(sess, 0, (sizeof(void *) * nb_drivers) + sizeof(uint8_t)); + memset(sess, 0, session_size); + rte_cryptodev_trace_asym_session_create(mp, sess); return sess; } @@ -1429,6 +1634,11 @@ rte_cryptodev_sym_session_clear(uint8_t dev_id, struct rte_cryptodev *dev; uint8_t driver_id; + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) { + CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id); + return -EINVAL; + } + dev = rte_cryptodev_pmd_get_dev(dev_id); if (dev == NULL || sess == NULL) @@ -1444,6 +1654,7 @@ rte_cryptodev_sym_session_clear(uint8_t dev_id, dev->dev_ops->sym_session_clear(dev, sess); + rte_cryptodev_trace_sym_session_clear(dev_id, sess); return 0; } @@ -1453,6 +1664,11 @@ rte_cryptodev_asym_session_clear(uint8_t dev_id, { struct rte_cryptodev *dev; + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) { + CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id); + return -EINVAL; + } + dev = rte_cryptodev_pmd_get_dev(dev_id); if (dev == NULL || sess == NULL) @@ -1462,6 +1678,7 @@ rte_cryptodev_asym_session_clear(uint8_t dev_id, dev->dev_ops->asym_session_clear(dev, sess); + rte_cryptodev_trace_sym_session_clear(dev_id, sess); return 0; } @@ -1484,6 +1701,7 @@ rte_cryptodev_sym_session_free(struct rte_cryptodev_sym_session *sess) sess_mp = rte_mempool_from_obj(sess); rte_mempool_put(sess_mp, sess); + rte_cryptodev_trace_sym_session_free(sess); return 0; } @@ -1508,6 +1726,7 @@ rte_cryptodev_asym_session_free(struct rte_cryptodev_asym_session *sess) sess_mp = rte_mempool_from_obj(sess); rte_mempool_put(sess_mp, sess); + rte_cryptodev_trace_asym_session_free(sess); return 0; } @@ -1617,6 +1836,37 @@ rte_cryptodev_sym_session_get_user_data( return (void *)(sess->sess_data + sess->nb_drivers); } +static inline void +sym_crypto_fill_status(struct rte_crypto_sym_vec *vec, int32_t errnum) +{ + uint32_t i; + for (i = 0; i < vec->num; i++) + vec->status[i] = errnum; +} + +uint32_t +rte_cryptodev_sym_cpu_crypto_process(uint8_t dev_id, + struct rte_cryptodev_sym_session *sess, union rte_crypto_sym_ofs ofs, + struct rte_crypto_sym_vec *vec) +{ + struct rte_cryptodev *dev; + + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) { + sym_crypto_fill_status(vec, EINVAL); + return 0; + } + + dev = rte_cryptodev_pmd_get_dev(dev_id); + + if (*dev->dev_ops->sym_cpu_process == NULL || + !(dev->feature_flags & RTE_CRYPTODEV_FF_SYM_CPU_CRYPTO)) { + sym_crypto_fill_status(vec, ENOTSUP); + return 0; + } + + return dev->dev_ops->sym_cpu_process(dev, sess, ofs, vec); +} + /** Initialise rte_crypto_op mempool element */ static void rte_crypto_op_init(struct rte_mempool *mempool, @@ -1755,8 +2005,14 @@ rte_cryptodev_driver_id_get(const char *name) const char * rte_cryptodev_name_get(uint8_t dev_id) { - struct rte_cryptodev *dev = rte_cryptodev_pmd_get_dev(dev_id); + struct rte_cryptodev *dev; + + if (!rte_cryptodev_is_valid_device_data(dev_id)) { + CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id); + return NULL; + } + dev = rte_cryptodev_pmd_get_dev(dev_id); if (dev == NULL) return NULL;