xref: /dpdk/lib/security/rte_security.c (revision 08966fe7f79fdaa5019b7559eebe84a1e3787b89)
199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
299a2dd95SBruce Richardson  * Copyright 2017 NXP.
399a2dd95SBruce Richardson  * Copyright(c) 2017 Intel Corporation.
499a2dd95SBruce Richardson  * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
599a2dd95SBruce Richardson  */
699a2dd95SBruce Richardson 
7*08966fe7STyler Retzlaff #include <stdalign.h>
872b452c5SDmitry Kozlyuk #include <ctype.h>
972b452c5SDmitry Kozlyuk #include <stdlib.h>
1072b452c5SDmitry Kozlyuk 
11259ca6d1SGowrishankar Muthukrishnan #include <rte_cryptodev.h>
121acb7f54SDavid Marchand #include <dev_driver.h>
13259ca6d1SGowrishankar Muthukrishnan #include <rte_telemetry.h>
1499a2dd95SBruce Richardson #include "rte_security.h"
1599a2dd95SBruce Richardson #include "rte_security_driver.h"
1699a2dd95SBruce Richardson 
1799a2dd95SBruce Richardson /* Macro to check for invalid pointers */
1899a2dd95SBruce Richardson #define RTE_PTR_OR_ERR_RET(ptr, retval) do {	\
1999a2dd95SBruce Richardson 	if ((ptr) == NULL)			\
2099a2dd95SBruce Richardson 		return retval;			\
2199a2dd95SBruce Richardson } while (0)
2299a2dd95SBruce Richardson 
2399a2dd95SBruce Richardson /* Macro to check for invalid pointers chains */
2499a2dd95SBruce Richardson #define RTE_PTR_CHAIN3_OR_ERR_RET(p1, p2, p3, retval, last_retval) do {	\
2599a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(p1, retval);					\
2699a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(p1->p2, retval);				\
2799a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(p1->p2->p3, last_retval);			\
2899a2dd95SBruce Richardson } while (0)
2999a2dd95SBruce Richardson 
3099a2dd95SBruce Richardson #define RTE_SECURITY_DYNFIELD_NAME "rte_security_dynfield_metadata"
311d63855bSNithin Dabilpuram #define RTE_SECURITY_OOP_DYNFIELD_NAME "rte_security_oop_dynfield_metadata"
321d63855bSNithin Dabilpuram 
3399a2dd95SBruce Richardson int rte_security_dynfield_offset = -1;
341d63855bSNithin Dabilpuram int rte_security_oop_dynfield_offset = -1;
3599a2dd95SBruce Richardson 
3699a2dd95SBruce Richardson int
rte_security_dynfield_register(void)3799a2dd95SBruce Richardson rte_security_dynfield_register(void)
3899a2dd95SBruce Richardson {
3999a2dd95SBruce Richardson 	static const struct rte_mbuf_dynfield dynfield_desc = {
4099a2dd95SBruce Richardson 		.name = RTE_SECURITY_DYNFIELD_NAME,
4199a2dd95SBruce Richardson 		.size = sizeof(rte_security_dynfield_t),
42*08966fe7STyler Retzlaff 		.align = alignof(rte_security_dynfield_t),
4399a2dd95SBruce Richardson 	};
4499a2dd95SBruce Richardson 	rte_security_dynfield_offset =
4599a2dd95SBruce Richardson 		rte_mbuf_dynfield_register(&dynfield_desc);
4699a2dd95SBruce Richardson 	return rte_security_dynfield_offset;
4799a2dd95SBruce Richardson }
4899a2dd95SBruce Richardson 
491d63855bSNithin Dabilpuram int
rte_security_oop_dynfield_register(void)501d63855bSNithin Dabilpuram rte_security_oop_dynfield_register(void)
511d63855bSNithin Dabilpuram {
521d63855bSNithin Dabilpuram 	static const struct rte_mbuf_dynfield dynfield_desc = {
531d63855bSNithin Dabilpuram 		.name = RTE_SECURITY_OOP_DYNFIELD_NAME,
541d63855bSNithin Dabilpuram 		.size = sizeof(rte_security_oop_dynfield_t),
55*08966fe7STyler Retzlaff 		.align = alignof(rte_security_oop_dynfield_t),
561d63855bSNithin Dabilpuram 	};
571d63855bSNithin Dabilpuram 
581d63855bSNithin Dabilpuram 	rte_security_oop_dynfield_offset =
591d63855bSNithin Dabilpuram 		rte_mbuf_dynfield_register(&dynfield_desc);
601d63855bSNithin Dabilpuram 	return rte_security_oop_dynfield_offset;
611d63855bSNithin Dabilpuram }
621d63855bSNithin Dabilpuram 
632973dbf9SAkhil Goyal void *
rte_security_session_create(void * ctx,struct rte_security_session_conf * conf,struct rte_mempool * mp)6479bdb787SAkhil Goyal rte_security_session_create(void *ctx,
6599a2dd95SBruce Richardson 			    struct rte_security_session_conf *conf,
663f3fc330SAkhil Goyal 			    struct rte_mempool *mp)
6799a2dd95SBruce Richardson {
6899a2dd95SBruce Richardson 	struct rte_security_session *sess = NULL;
6979bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
703f3fc330SAkhil Goyal 	uint32_t sess_priv_size;
7199a2dd95SBruce Richardson 
7299a2dd95SBruce Richardson 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_create, NULL, NULL);
7399a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(conf, NULL);
7499a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(mp, NULL);
753f3fc330SAkhil Goyal 
763f3fc330SAkhil Goyal 	sess_priv_size = instance->ops->session_get_size(instance->device);
773f3fc330SAkhil Goyal 	if (mp->elt_size < (sizeof(struct rte_security_session) + sess_priv_size))
783f3fc330SAkhil Goyal 		return NULL;
7999a2dd95SBruce Richardson 
8099a2dd95SBruce Richardson 	if (rte_mempool_get(mp, (void **)&sess))
8199a2dd95SBruce Richardson 		return NULL;
8299a2dd95SBruce Richardson 
833f3fc330SAkhil Goyal 	/* Clear session priv data */
843f3fc330SAkhil Goyal 	memset(sess->driver_priv_data, 0, sess_priv_size);
853f3fc330SAkhil Goyal 
863f3fc330SAkhil Goyal 	sess->driver_priv_data_iova = rte_mempool_virt2iova(sess) +
873f3fc330SAkhil Goyal 			offsetof(struct rte_security_session, driver_priv_data);
883f3fc330SAkhil Goyal 	if (instance->ops->session_create(instance->device, conf, sess)) {
8999a2dd95SBruce Richardson 		rte_mempool_put(mp, (void *)sess);
9099a2dd95SBruce Richardson 		return NULL;
9199a2dd95SBruce Richardson 	}
9299a2dd95SBruce Richardson 	instance->sess_cnt++;
9399a2dd95SBruce Richardson 
942973dbf9SAkhil Goyal 	return (void *)sess;
9599a2dd95SBruce Richardson }
9699a2dd95SBruce Richardson 
9799a2dd95SBruce Richardson int
rte_security_session_update(void * ctx,void * sess,struct rte_security_session_conf * conf)9879bdb787SAkhil Goyal rte_security_session_update(void *ctx, void *sess, struct rte_security_session_conf *conf)
9999a2dd95SBruce Richardson {
10079bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
10179bdb787SAkhil Goyal 
10299a2dd95SBruce Richardson 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_update, -EINVAL,
10399a2dd95SBruce Richardson 			-ENOTSUP);
10499a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(sess, -EINVAL);
10599a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(conf, -EINVAL);
10699a2dd95SBruce Richardson 
10799a2dd95SBruce Richardson 	return instance->ops->session_update(instance->device, sess, conf);
10899a2dd95SBruce Richardson }
10999a2dd95SBruce Richardson 
11099a2dd95SBruce Richardson unsigned int
rte_security_session_get_size(void * ctx)11179bdb787SAkhil Goyal rte_security_session_get_size(void *ctx)
11299a2dd95SBruce Richardson {
11379bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
11479bdb787SAkhil Goyal 
11599a2dd95SBruce Richardson 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_get_size, 0, 0);
11699a2dd95SBruce Richardson 
1173f3fc330SAkhil Goyal 	return (sizeof(struct rte_security_session) +
1183f3fc330SAkhil Goyal 			instance->ops->session_get_size(instance->device));
11999a2dd95SBruce Richardson }
12099a2dd95SBruce Richardson 
12199a2dd95SBruce Richardson int
rte_security_session_stats_get(void * ctx,void * sess,struct rte_security_stats * stats)12279bdb787SAkhil Goyal rte_security_session_stats_get(void *ctx, void *sess, struct rte_security_stats *stats)
12399a2dd95SBruce Richardson {
12479bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
12579bdb787SAkhil Goyal 
12699a2dd95SBruce Richardson 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_stats_get, -EINVAL,
12799a2dd95SBruce Richardson 			-ENOTSUP);
12899a2dd95SBruce Richardson 	/* Parameter sess can be NULL in case of getting global statistics. */
12999a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(stats, -EINVAL);
13099a2dd95SBruce Richardson 
13199a2dd95SBruce Richardson 	return instance->ops->session_stats_get(instance->device, sess, stats);
13299a2dd95SBruce Richardson }
13399a2dd95SBruce Richardson 
13499a2dd95SBruce Richardson int
rte_security_session_destroy(void * ctx,void * sess)13579bdb787SAkhil Goyal rte_security_session_destroy(void *ctx, void *sess)
13699a2dd95SBruce Richardson {
13779bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
13899a2dd95SBruce Richardson 	int ret;
13999a2dd95SBruce Richardson 
14099a2dd95SBruce Richardson 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_destroy, -EINVAL,
14199a2dd95SBruce Richardson 			-ENOTSUP);
14299a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(sess, -EINVAL);
14399a2dd95SBruce Richardson 
14499a2dd95SBruce Richardson 	ret = instance->ops->session_destroy(instance->device, sess);
14599a2dd95SBruce Richardson 	if (ret != 0)
14699a2dd95SBruce Richardson 		return ret;
14799a2dd95SBruce Richardson 
14899a2dd95SBruce Richardson 	rte_mempool_put(rte_mempool_from_obj(sess), (void *)sess);
14999a2dd95SBruce Richardson 
15099a2dd95SBruce Richardson 	if (instance->sess_cnt)
15199a2dd95SBruce Richardson 		instance->sess_cnt--;
15299a2dd95SBruce Richardson 
15399a2dd95SBruce Richardson 	return 0;
15499a2dd95SBruce Richardson }
15599a2dd95SBruce Richardson 
15699a2dd95SBruce Richardson int
rte_security_macsec_sc_create(void * ctx,struct rte_security_macsec_sc * conf)15779bdb787SAkhil Goyal rte_security_macsec_sc_create(void *ctx, struct rte_security_macsec_sc *conf)
158bbbe6c59SAkhil Goyal {
15979bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
160bbbe6c59SAkhil Goyal 	int sc_id;
161bbbe6c59SAkhil Goyal 
162bbbe6c59SAkhil Goyal 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, macsec_sc_create, -EINVAL, -ENOTSUP);
163bbbe6c59SAkhil Goyal 	RTE_PTR_OR_ERR_RET(conf, -EINVAL);
164bbbe6c59SAkhil Goyal 
165bbbe6c59SAkhil Goyal 	sc_id = instance->ops->macsec_sc_create(instance->device, conf);
166bbbe6c59SAkhil Goyal 	if (sc_id >= 0)
167bbbe6c59SAkhil Goyal 		instance->macsec_sc_cnt++;
168bbbe6c59SAkhil Goyal 
169bbbe6c59SAkhil Goyal 	return sc_id;
170bbbe6c59SAkhil Goyal }
171bbbe6c59SAkhil Goyal 
172bbbe6c59SAkhil Goyal int
rte_security_macsec_sa_create(void * ctx,struct rte_security_macsec_sa * conf)17379bdb787SAkhil Goyal rte_security_macsec_sa_create(void *ctx, struct rte_security_macsec_sa *conf)
174bbbe6c59SAkhil Goyal {
17579bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
176bbbe6c59SAkhil Goyal 	int sa_id;
177bbbe6c59SAkhil Goyal 
178bbbe6c59SAkhil Goyal 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, macsec_sa_create, -EINVAL, -ENOTSUP);
179bbbe6c59SAkhil Goyal 	RTE_PTR_OR_ERR_RET(conf, -EINVAL);
180bbbe6c59SAkhil Goyal 
181bbbe6c59SAkhil Goyal 	sa_id = instance->ops->macsec_sa_create(instance->device, conf);
182bbbe6c59SAkhil Goyal 	if (sa_id >= 0)
183bbbe6c59SAkhil Goyal 		instance->macsec_sa_cnt++;
184bbbe6c59SAkhil Goyal 
185bbbe6c59SAkhil Goyal 	return sa_id;
186bbbe6c59SAkhil Goyal }
187bbbe6c59SAkhil Goyal 
188bbbe6c59SAkhil Goyal int
rte_security_macsec_sc_destroy(void * ctx,uint16_t sc_id,enum rte_security_macsec_direction dir)18979bdb787SAkhil Goyal rte_security_macsec_sc_destroy(void *ctx, uint16_t sc_id,
190b241a5adSAkhil Goyal 			       enum rte_security_macsec_direction dir)
191bbbe6c59SAkhil Goyal {
19279bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
193bbbe6c59SAkhil Goyal 	int ret;
194bbbe6c59SAkhil Goyal 
195bbbe6c59SAkhil Goyal 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, macsec_sc_destroy, -EINVAL, -ENOTSUP);
196bbbe6c59SAkhil Goyal 
197b241a5adSAkhil Goyal 	ret = instance->ops->macsec_sc_destroy(instance->device, sc_id, dir);
198bbbe6c59SAkhil Goyal 	if (ret != 0)
199bbbe6c59SAkhil Goyal 		return ret;
200bbbe6c59SAkhil Goyal 
201bbbe6c59SAkhil Goyal 	if (instance->macsec_sc_cnt)
202bbbe6c59SAkhil Goyal 		instance->macsec_sc_cnt--;
203bbbe6c59SAkhil Goyal 
204bbbe6c59SAkhil Goyal 	return 0;
205bbbe6c59SAkhil Goyal }
206bbbe6c59SAkhil Goyal 
207bbbe6c59SAkhil Goyal int
rte_security_macsec_sa_destroy(void * ctx,uint16_t sa_id,enum rte_security_macsec_direction dir)20879bdb787SAkhil Goyal rte_security_macsec_sa_destroy(void *ctx, uint16_t sa_id,
209b241a5adSAkhil Goyal 			       enum rte_security_macsec_direction dir)
210bbbe6c59SAkhil Goyal {
21179bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
212bbbe6c59SAkhil Goyal 	int ret;
213bbbe6c59SAkhil Goyal 
214bbbe6c59SAkhil Goyal 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, macsec_sa_destroy, -EINVAL, -ENOTSUP);
215bbbe6c59SAkhil Goyal 
216b241a5adSAkhil Goyal 	ret = instance->ops->macsec_sa_destroy(instance->device, sa_id, dir);
217bbbe6c59SAkhil Goyal 	if (ret != 0)
218bbbe6c59SAkhil Goyal 		return ret;
219bbbe6c59SAkhil Goyal 
220bbbe6c59SAkhil Goyal 	if (instance->macsec_sa_cnt)
221bbbe6c59SAkhil Goyal 		instance->macsec_sa_cnt--;
222bbbe6c59SAkhil Goyal 
223bbbe6c59SAkhil Goyal 	return 0;
224bbbe6c59SAkhil Goyal }
225bbbe6c59SAkhil Goyal 
226bbbe6c59SAkhil Goyal int
rte_security_macsec_sc_stats_get(void * ctx,uint16_t sc_id,enum rte_security_macsec_direction dir,struct rte_security_macsec_sc_stats * stats)22779bdb787SAkhil Goyal rte_security_macsec_sc_stats_get(void *ctx, uint16_t sc_id,
228b241a5adSAkhil Goyal 				 enum rte_security_macsec_direction dir,
229bbbe6c59SAkhil Goyal 				 struct rte_security_macsec_sc_stats *stats)
230bbbe6c59SAkhil Goyal {
23179bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
23279bdb787SAkhil Goyal 
233bbbe6c59SAkhil Goyal 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, macsec_sc_stats_get, -EINVAL, -ENOTSUP);
234bbbe6c59SAkhil Goyal 	RTE_PTR_OR_ERR_RET(stats, -EINVAL);
235bbbe6c59SAkhil Goyal 
236b241a5adSAkhil Goyal 	return instance->ops->macsec_sc_stats_get(instance->device, sc_id, dir, stats);
237bbbe6c59SAkhil Goyal }
238bbbe6c59SAkhil Goyal 
239bbbe6c59SAkhil Goyal int
rte_security_macsec_sa_stats_get(void * ctx,uint16_t sa_id,enum rte_security_macsec_direction dir,struct rte_security_macsec_sa_stats * stats)24079bdb787SAkhil Goyal rte_security_macsec_sa_stats_get(void *ctx, uint16_t sa_id,
241b241a5adSAkhil Goyal 				 enum rte_security_macsec_direction dir,
242bbbe6c59SAkhil Goyal 				 struct rte_security_macsec_sa_stats *stats)
243bbbe6c59SAkhil Goyal {
24479bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
24579bdb787SAkhil Goyal 
246bbbe6c59SAkhil Goyal 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, macsec_sa_stats_get, -EINVAL, -ENOTSUP);
247bbbe6c59SAkhil Goyal 	RTE_PTR_OR_ERR_RET(stats, -EINVAL);
248bbbe6c59SAkhil Goyal 
249b241a5adSAkhil Goyal 	return instance->ops->macsec_sa_stats_get(instance->device, sa_id, dir, stats);
250bbbe6c59SAkhil Goyal }
251bbbe6c59SAkhil Goyal 
252bbbe6c59SAkhil Goyal int
__rte_security_set_pkt_metadata(void * ctx,void * sess,struct rte_mbuf * m,void * params)25379bdb787SAkhil Goyal __rte_security_set_pkt_metadata(void *ctx, void *sess, struct rte_mbuf *m, void *params)
25499a2dd95SBruce Richardson {
25579bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
25699a2dd95SBruce Richardson #ifdef RTE_DEBUG
25799a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(sess, -EINVAL);
25899a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(instance, -EINVAL);
25999a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(instance->ops, -EINVAL);
26099a2dd95SBruce Richardson #endif
2618f1d23ecSDavid Marchand 	if (*instance->ops->set_pkt_metadata == NULL)
2628f1d23ecSDavid Marchand 		return -ENOTSUP;
26399a2dd95SBruce Richardson 	return instance->ops->set_pkt_metadata(instance->device,
26499a2dd95SBruce Richardson 					       sess, m, params);
26599a2dd95SBruce Richardson }
26699a2dd95SBruce Richardson 
26799a2dd95SBruce Richardson const struct rte_security_capability *
rte_security_capabilities_get(void * ctx)26879bdb787SAkhil Goyal rte_security_capabilities_get(void *ctx)
26999a2dd95SBruce Richardson {
27079bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
27179bdb787SAkhil Goyal 
27299a2dd95SBruce Richardson 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, capabilities_get, NULL, NULL);
27399a2dd95SBruce Richardson 
27499a2dd95SBruce Richardson 	return instance->ops->capabilities_get(instance->device);
27599a2dd95SBruce Richardson }
27699a2dd95SBruce Richardson 
27799a2dd95SBruce Richardson const struct rte_security_capability *
rte_security_capability_get(void * ctx,struct rte_security_capability_idx * idx)27879bdb787SAkhil Goyal rte_security_capability_get(void *ctx, struct rte_security_capability_idx *idx)
27999a2dd95SBruce Richardson {
28099a2dd95SBruce Richardson 	const struct rte_security_capability *capabilities;
28199a2dd95SBruce Richardson 	const struct rte_security_capability *capability;
28279bdb787SAkhil Goyal 	struct rte_security_ctx *instance = ctx;
28399a2dd95SBruce Richardson 	uint16_t i = 0;
28499a2dd95SBruce Richardson 
28599a2dd95SBruce Richardson 	RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, capabilities_get, NULL, NULL);
28699a2dd95SBruce Richardson 	RTE_PTR_OR_ERR_RET(idx, NULL);
28799a2dd95SBruce Richardson 
28899a2dd95SBruce Richardson 	capabilities = instance->ops->capabilities_get(instance->device);
28999a2dd95SBruce Richardson 
29099a2dd95SBruce Richardson 	if (capabilities == NULL)
29199a2dd95SBruce Richardson 		return NULL;
29299a2dd95SBruce Richardson 
29399a2dd95SBruce Richardson 	while ((capability = &capabilities[i++])->action
29499a2dd95SBruce Richardson 			!= RTE_SECURITY_ACTION_TYPE_NONE) {
29599a2dd95SBruce Richardson 		if (capability->action == idx->action &&
29699a2dd95SBruce Richardson 				capability->protocol == idx->protocol) {
29799a2dd95SBruce Richardson 			if (idx->protocol == RTE_SECURITY_PROTOCOL_IPSEC) {
29899a2dd95SBruce Richardson 				if (capability->ipsec.proto ==
29999a2dd95SBruce Richardson 						idx->ipsec.proto &&
30099a2dd95SBruce Richardson 					capability->ipsec.mode ==
30199a2dd95SBruce Richardson 							idx->ipsec.mode &&
30299a2dd95SBruce Richardson 					capability->ipsec.direction ==
30399a2dd95SBruce Richardson 							idx->ipsec.direction)
30499a2dd95SBruce Richardson 					return capability;
30599a2dd95SBruce Richardson 			} else if (idx->protocol == RTE_SECURITY_PROTOCOL_PDCP) {
30699a2dd95SBruce Richardson 				if (capability->pdcp.domain ==
30799a2dd95SBruce Richardson 							idx->pdcp.domain)
30899a2dd95SBruce Richardson 					return capability;
30999a2dd95SBruce Richardson 			} else if (idx->protocol ==
31099a2dd95SBruce Richardson 						RTE_SECURITY_PROTOCOL_DOCSIS) {
31199a2dd95SBruce Richardson 				if (capability->docsis.direction ==
31299a2dd95SBruce Richardson 							idx->docsis.direction)
31399a2dd95SBruce Richardson 					return capability;
314a35f828dSAnkur Dwivedi 			} else if (idx->protocol ==
315a35f828dSAnkur Dwivedi 						RTE_SECURITY_PROTOCOL_MACSEC) {
316a35f828dSAnkur Dwivedi 				if (idx->macsec.alg == capability->macsec.alg)
317a35f828dSAnkur Dwivedi 					return capability;
3187ebdf16aSAnoob Joseph 			} else if (idx->protocol == RTE_SECURITY_PROTOCOL_TLS_RECORD) {
3197ebdf16aSAnoob Joseph 				if (capability->tls_record.ver == idx->tls_record.ver &&
3207ebdf16aSAnoob Joseph 				    capability->tls_record.type == idx->tls_record.type)
3217ebdf16aSAnoob Joseph 					return capability;
32299a2dd95SBruce Richardson 			}
32399a2dd95SBruce Richardson 		}
32499a2dd95SBruce Richardson 	}
32599a2dd95SBruce Richardson 
32699a2dd95SBruce Richardson 	return NULL;
32799a2dd95SBruce Richardson }
328259ca6d1SGowrishankar Muthukrishnan 
329165bb658SAnoob Joseph int
rte_security_rx_inject_configure(void * ctx,uint16_t port_id,bool enable)330165bb658SAnoob Joseph rte_security_rx_inject_configure(void *ctx, uint16_t port_id, bool enable)
331165bb658SAnoob Joseph {
332165bb658SAnoob Joseph 	struct rte_security_ctx *instance = ctx;
333165bb658SAnoob Joseph 
334165bb658SAnoob Joseph 	RTE_PTR_OR_ERR_RET(instance, -EINVAL);
335165bb658SAnoob Joseph 	RTE_PTR_OR_ERR_RET(instance->ops, -ENOTSUP);
336165bb658SAnoob Joseph 	RTE_PTR_OR_ERR_RET(instance->ops->rx_inject_configure, -ENOTSUP);
337165bb658SAnoob Joseph 
338165bb658SAnoob Joseph 	return instance->ops->rx_inject_configure(instance->device, port_id, enable);
339165bb658SAnoob Joseph }
340165bb658SAnoob Joseph 
341165bb658SAnoob Joseph uint16_t
rte_security_inb_pkt_rx_inject(void * ctx,struct rte_mbuf ** pkts,void ** sess,uint16_t nb_pkts)342165bb658SAnoob Joseph rte_security_inb_pkt_rx_inject(void *ctx, struct rte_mbuf **pkts, void **sess,
343165bb658SAnoob Joseph 			       uint16_t nb_pkts)
344165bb658SAnoob Joseph {
345165bb658SAnoob Joseph 	struct rte_security_ctx *instance = ctx;
346165bb658SAnoob Joseph 
347165bb658SAnoob Joseph 	return instance->ops->inb_pkt_rx_inject(instance->device, pkts,
348165bb658SAnoob Joseph 						(struct rte_security_session **)sess, nb_pkts);
349165bb658SAnoob Joseph }
350165bb658SAnoob Joseph 
351259ca6d1SGowrishankar Muthukrishnan static int
security_handle_cryptodev_list(const char * cmd __rte_unused,const char * params __rte_unused,struct rte_tel_data * d)352259ca6d1SGowrishankar Muthukrishnan security_handle_cryptodev_list(const char *cmd __rte_unused,
353259ca6d1SGowrishankar Muthukrishnan 			       const char *params __rte_unused,
354259ca6d1SGowrishankar Muthukrishnan 			       struct rte_tel_data *d)
355259ca6d1SGowrishankar Muthukrishnan {
356259ca6d1SGowrishankar Muthukrishnan 	int dev_id;
357259ca6d1SGowrishankar Muthukrishnan 
358259ca6d1SGowrishankar Muthukrishnan 	if (rte_cryptodev_count() < 1)
359259ca6d1SGowrishankar Muthukrishnan 		return -1;
360259ca6d1SGowrishankar Muthukrishnan 
361259ca6d1SGowrishankar Muthukrishnan 	rte_tel_data_start_array(d, RTE_TEL_INT_VAL);
362259ca6d1SGowrishankar Muthukrishnan 	for (dev_id = 0; dev_id < RTE_CRYPTO_MAX_DEVS; dev_id++)
363259ca6d1SGowrishankar Muthukrishnan 		if (rte_cryptodev_is_valid_dev(dev_id) &&
364259ca6d1SGowrishankar Muthukrishnan 		    rte_cryptodev_get_sec_ctx(dev_id))
365259ca6d1SGowrishankar Muthukrishnan 			rte_tel_data_add_array_int(d, dev_id);
366259ca6d1SGowrishankar Muthukrishnan 
367259ca6d1SGowrishankar Muthukrishnan 	return 0;
368259ca6d1SGowrishankar Muthukrishnan }
369259ca6d1SGowrishankar Muthukrishnan 
370259ca6d1SGowrishankar Muthukrishnan #define CRYPTO_CAPS_SZ                                             \
371259ca6d1SGowrishankar Muthukrishnan 	(RTE_ALIGN_CEIL(sizeof(struct rte_cryptodev_capabilities), \
372259ca6d1SGowrishankar Muthukrishnan 			sizeof(uint64_t)) /	sizeof(uint64_t))
373259ca6d1SGowrishankar Muthukrishnan 
374259ca6d1SGowrishankar Muthukrishnan static int
crypto_caps_array(struct rte_tel_data * d,const struct rte_cryptodev_capabilities * capabilities)375259ca6d1SGowrishankar Muthukrishnan crypto_caps_array(struct rte_tel_data *d,
376259ca6d1SGowrishankar Muthukrishnan 		  const struct rte_cryptodev_capabilities *capabilities)
377259ca6d1SGowrishankar Muthukrishnan {
378259ca6d1SGowrishankar Muthukrishnan 	const struct rte_cryptodev_capabilities *dev_caps;
379259ca6d1SGowrishankar Muthukrishnan 	uint64_t caps_val[CRYPTO_CAPS_SZ];
380259ca6d1SGowrishankar Muthukrishnan 	unsigned int i = 0, j;
381259ca6d1SGowrishankar Muthukrishnan 
3822d2c55e4SBruce Richardson 	rte_tel_data_start_array(d, RTE_TEL_UINT_VAL);
383259ca6d1SGowrishankar Muthukrishnan 
384259ca6d1SGowrishankar Muthukrishnan 	while ((dev_caps = &capabilities[i++])->op !=
385259ca6d1SGowrishankar Muthukrishnan 	   RTE_CRYPTO_OP_TYPE_UNDEFINED) {
386259ca6d1SGowrishankar Muthukrishnan 		memset(&caps_val, 0, CRYPTO_CAPS_SZ * sizeof(caps_val[0]));
387259ca6d1SGowrishankar Muthukrishnan 		rte_memcpy(caps_val, dev_caps, sizeof(capabilities[0]));
388259ca6d1SGowrishankar Muthukrishnan 		for (j = 0; j < CRYPTO_CAPS_SZ; j++)
389af0785a2SBruce Richardson 			rte_tel_data_add_array_uint(d, caps_val[j]);
390259ca6d1SGowrishankar Muthukrishnan 	}
391259ca6d1SGowrishankar Muthukrishnan 
392259ca6d1SGowrishankar Muthukrishnan 	return (i - 1);
393259ca6d1SGowrishankar Muthukrishnan }
394259ca6d1SGowrishankar Muthukrishnan 
395259ca6d1SGowrishankar Muthukrishnan #define SEC_CAPS_SZ						\
396259ca6d1SGowrishankar Muthukrishnan 	(RTE_ALIGN_CEIL(sizeof(struct rte_security_capability), \
397259ca6d1SGowrishankar Muthukrishnan 			sizeof(uint64_t)) /	sizeof(uint64_t))
398259ca6d1SGowrishankar Muthukrishnan 
399259ca6d1SGowrishankar Muthukrishnan static int
sec_caps_array(struct rte_tel_data * d,const struct rte_security_capability * capabilities)400259ca6d1SGowrishankar Muthukrishnan sec_caps_array(struct rte_tel_data *d,
401259ca6d1SGowrishankar Muthukrishnan 	       const struct rte_security_capability *capabilities)
402259ca6d1SGowrishankar Muthukrishnan {
403259ca6d1SGowrishankar Muthukrishnan 	const struct rte_security_capability *dev_caps;
404259ca6d1SGowrishankar Muthukrishnan 	uint64_t caps_val[SEC_CAPS_SZ];
405259ca6d1SGowrishankar Muthukrishnan 	unsigned int i = 0, j;
406259ca6d1SGowrishankar Muthukrishnan 
4072d2c55e4SBruce Richardson 	rte_tel_data_start_array(d, RTE_TEL_UINT_VAL);
408259ca6d1SGowrishankar Muthukrishnan 
409259ca6d1SGowrishankar Muthukrishnan 	while ((dev_caps = &capabilities[i++])->action !=
410259ca6d1SGowrishankar Muthukrishnan 	   RTE_SECURITY_ACTION_TYPE_NONE) {
411259ca6d1SGowrishankar Muthukrishnan 		memset(&caps_val, 0, SEC_CAPS_SZ * sizeof(caps_val[0]));
412259ca6d1SGowrishankar Muthukrishnan 		rte_memcpy(caps_val, dev_caps, sizeof(capabilities[0]));
413259ca6d1SGowrishankar Muthukrishnan 		for (j = 0; j < SEC_CAPS_SZ; j++)
414af0785a2SBruce Richardson 			rte_tel_data_add_array_uint(d, caps_val[j]);
415259ca6d1SGowrishankar Muthukrishnan 	}
416259ca6d1SGowrishankar Muthukrishnan 
417259ca6d1SGowrishankar Muthukrishnan 	return i - 1;
418259ca6d1SGowrishankar Muthukrishnan }
419259ca6d1SGowrishankar Muthukrishnan 
420259ca6d1SGowrishankar Muthukrishnan static const struct rte_security_capability *
security_capability_by_index(const struct rte_security_capability * capabilities,int index)421259ca6d1SGowrishankar Muthukrishnan security_capability_by_index(const struct rte_security_capability *capabilities,
422259ca6d1SGowrishankar Muthukrishnan 			     int index)
423259ca6d1SGowrishankar Muthukrishnan {
424259ca6d1SGowrishankar Muthukrishnan 	const struct rte_security_capability *dev_caps = NULL;
425259ca6d1SGowrishankar Muthukrishnan 	int i = 0;
426259ca6d1SGowrishankar Muthukrishnan 
427259ca6d1SGowrishankar Muthukrishnan 	while ((dev_caps = &capabilities[i])->action !=
428259ca6d1SGowrishankar Muthukrishnan 	   RTE_SECURITY_ACTION_TYPE_NONE) {
429259ca6d1SGowrishankar Muthukrishnan 		if (i == index)
430259ca6d1SGowrishankar Muthukrishnan 			return dev_caps;
431259ca6d1SGowrishankar Muthukrishnan 
432259ca6d1SGowrishankar Muthukrishnan 		++i;
433259ca6d1SGowrishankar Muthukrishnan 	}
434259ca6d1SGowrishankar Muthukrishnan 
435259ca6d1SGowrishankar Muthukrishnan 	return NULL;
436259ca6d1SGowrishankar Muthukrishnan }
437259ca6d1SGowrishankar Muthukrishnan 
438259ca6d1SGowrishankar Muthukrishnan static int
security_capabilities_from_dev_id(int dev_id,const void ** caps)439259ca6d1SGowrishankar Muthukrishnan security_capabilities_from_dev_id(int dev_id, const void **caps)
440259ca6d1SGowrishankar Muthukrishnan {
441259ca6d1SGowrishankar Muthukrishnan 	const struct rte_security_capability *capabilities;
44279bdb787SAkhil Goyal 	void *sec_ctx;
443259ca6d1SGowrishankar Muthukrishnan 
444259ca6d1SGowrishankar Muthukrishnan 	if (rte_cryptodev_is_valid_dev(dev_id) == 0)
445259ca6d1SGowrishankar Muthukrishnan 		return -EINVAL;
446259ca6d1SGowrishankar Muthukrishnan 
44779bdb787SAkhil Goyal 	sec_ctx = rte_cryptodev_get_sec_ctx(dev_id);
448259ca6d1SGowrishankar Muthukrishnan 	RTE_PTR_OR_ERR_RET(sec_ctx, -EINVAL);
449259ca6d1SGowrishankar Muthukrishnan 
450259ca6d1SGowrishankar Muthukrishnan 	capabilities = rte_security_capabilities_get(sec_ctx);
451259ca6d1SGowrishankar Muthukrishnan 	RTE_PTR_OR_ERR_RET(capabilities, -EINVAL);
452259ca6d1SGowrishankar Muthukrishnan 
453259ca6d1SGowrishankar Muthukrishnan 	*caps = capabilities;
454259ca6d1SGowrishankar Muthukrishnan 	return 0;
455259ca6d1SGowrishankar Muthukrishnan }
456259ca6d1SGowrishankar Muthukrishnan 
457259ca6d1SGowrishankar Muthukrishnan static int
security_handle_cryptodev_sec_caps(const char * cmd __rte_unused,const char * params,struct rte_tel_data * d)458259ca6d1SGowrishankar Muthukrishnan security_handle_cryptodev_sec_caps(const char *cmd __rte_unused, const char *params,
459259ca6d1SGowrishankar Muthukrishnan 				   struct rte_tel_data *d)
460259ca6d1SGowrishankar Muthukrishnan {
461259ca6d1SGowrishankar Muthukrishnan 	const struct rte_security_capability *capabilities;
462259ca6d1SGowrishankar Muthukrishnan 	struct rte_tel_data *sec_caps;
463259ca6d1SGowrishankar Muthukrishnan 	char *end_param;
464259ca6d1SGowrishankar Muthukrishnan 	int sec_caps_n;
465259ca6d1SGowrishankar Muthukrishnan 	int dev_id;
466259ca6d1SGowrishankar Muthukrishnan 	int rc;
467259ca6d1SGowrishankar Muthukrishnan 
468259ca6d1SGowrishankar Muthukrishnan 	if (!params || strlen(params) == 0 || !isdigit(*params))
469259ca6d1SGowrishankar Muthukrishnan 		return -EINVAL;
470259ca6d1SGowrishankar Muthukrishnan 
471259ca6d1SGowrishankar Muthukrishnan 	dev_id = strtoul(params, &end_param, 0);
472259ca6d1SGowrishankar Muthukrishnan 	if (*end_param != '\0')
473259ca6d1SGowrishankar Muthukrishnan 		CDEV_LOG_ERR("Extra parameters passed to command, ignoring");
474259ca6d1SGowrishankar Muthukrishnan 
475259ca6d1SGowrishankar Muthukrishnan 	rc = security_capabilities_from_dev_id(dev_id, (void *)&capabilities);
476259ca6d1SGowrishankar Muthukrishnan 	if (rc < 0)
477259ca6d1SGowrishankar Muthukrishnan 		return rc;
478259ca6d1SGowrishankar Muthukrishnan 
479259ca6d1SGowrishankar Muthukrishnan 	sec_caps = rte_tel_data_alloc();
480259ca6d1SGowrishankar Muthukrishnan 	RTE_PTR_OR_ERR_RET(sec_caps, -ENOMEM);
481259ca6d1SGowrishankar Muthukrishnan 
482259ca6d1SGowrishankar Muthukrishnan 	rte_tel_data_start_dict(d);
483259ca6d1SGowrishankar Muthukrishnan 	sec_caps_n = sec_caps_array(sec_caps, capabilities);
484259ca6d1SGowrishankar Muthukrishnan 	rte_tel_data_add_dict_container(d, "sec_caps", sec_caps, 0);
485259ca6d1SGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "sec_caps_n", sec_caps_n);
486259ca6d1SGowrishankar Muthukrishnan 
487259ca6d1SGowrishankar Muthukrishnan 	return 0;
488259ca6d1SGowrishankar Muthukrishnan }
489259ca6d1SGowrishankar Muthukrishnan 
490259ca6d1SGowrishankar Muthukrishnan static int
security_handle_cryptodev_crypto_caps(const char * cmd __rte_unused,const char * params,struct rte_tel_data * d)491259ca6d1SGowrishankar Muthukrishnan security_handle_cryptodev_crypto_caps(const char *cmd __rte_unused, const char *params,
492259ca6d1SGowrishankar Muthukrishnan 				      struct rte_tel_data *d)
493259ca6d1SGowrishankar Muthukrishnan {
494259ca6d1SGowrishankar Muthukrishnan 	const struct rte_security_capability *capabilities;
495259ca6d1SGowrishankar Muthukrishnan 	struct rte_tel_data *crypto_caps;
496259ca6d1SGowrishankar Muthukrishnan 	const char *capa_param;
497259ca6d1SGowrishankar Muthukrishnan 	int dev_id, capa_id;
498259ca6d1SGowrishankar Muthukrishnan 	int crypto_caps_n;
499259ca6d1SGowrishankar Muthukrishnan 	char *end_param;
500259ca6d1SGowrishankar Muthukrishnan 	int rc;
501259ca6d1SGowrishankar Muthukrishnan 
502259ca6d1SGowrishankar Muthukrishnan 	if (!params || strlen(params) == 0 || !isdigit(*params))
503259ca6d1SGowrishankar Muthukrishnan 		return -EINVAL;
504259ca6d1SGowrishankar Muthukrishnan 
505259ca6d1SGowrishankar Muthukrishnan 	dev_id = strtoul(params, &end_param, 0);
506259ca6d1SGowrishankar Muthukrishnan 	capa_param = strtok(end_param, ",");
507259ca6d1SGowrishankar Muthukrishnan 	if (!capa_param || strlen(capa_param) == 0 || !isdigit(*capa_param))
508259ca6d1SGowrishankar Muthukrishnan 		return -EINVAL;
509259ca6d1SGowrishankar Muthukrishnan 
510259ca6d1SGowrishankar Muthukrishnan 	capa_id = strtoul(capa_param, &end_param, 0);
511259ca6d1SGowrishankar Muthukrishnan 	if (*end_param != '\0')
512259ca6d1SGowrishankar Muthukrishnan 		CDEV_LOG_ERR("Extra parameters passed to command, ignoring");
513259ca6d1SGowrishankar Muthukrishnan 
514259ca6d1SGowrishankar Muthukrishnan 	rc = security_capabilities_from_dev_id(dev_id, (void *)&capabilities);
515259ca6d1SGowrishankar Muthukrishnan 	if (rc < 0)
516259ca6d1SGowrishankar Muthukrishnan 		return rc;
517259ca6d1SGowrishankar Muthukrishnan 
518259ca6d1SGowrishankar Muthukrishnan 	capabilities = security_capability_by_index(capabilities, capa_id);
519259ca6d1SGowrishankar Muthukrishnan 	RTE_PTR_OR_ERR_RET(capabilities, -EINVAL);
520259ca6d1SGowrishankar Muthukrishnan 
521259ca6d1SGowrishankar Muthukrishnan 	crypto_caps = rte_tel_data_alloc();
522259ca6d1SGowrishankar Muthukrishnan 	RTE_PTR_OR_ERR_RET(crypto_caps, -ENOMEM);
523259ca6d1SGowrishankar Muthukrishnan 
524259ca6d1SGowrishankar Muthukrishnan 	rte_tel_data_start_dict(d);
525259ca6d1SGowrishankar Muthukrishnan 	crypto_caps_n = crypto_caps_array(crypto_caps, capabilities->crypto_capabilities);
526259ca6d1SGowrishankar Muthukrishnan 
527259ca6d1SGowrishankar Muthukrishnan 	rte_tel_data_add_dict_container(d, "crypto_caps", crypto_caps, 0);
528259ca6d1SGowrishankar Muthukrishnan 	rte_tel_data_add_dict_int(d, "crypto_caps_n", crypto_caps_n);
529259ca6d1SGowrishankar Muthukrishnan 
530259ca6d1SGowrishankar Muthukrishnan 	return 0;
531259ca6d1SGowrishankar Muthukrishnan }
532259ca6d1SGowrishankar Muthukrishnan 
RTE_INIT(security_init_telemetry)533259ca6d1SGowrishankar Muthukrishnan RTE_INIT(security_init_telemetry)
534259ca6d1SGowrishankar Muthukrishnan {
535259ca6d1SGowrishankar Muthukrishnan 	rte_telemetry_register_cmd("/security/cryptodev/list",
536259ca6d1SGowrishankar Muthukrishnan 		security_handle_cryptodev_list,
537259ca6d1SGowrishankar Muthukrishnan 		"Returns list of available crypto devices by IDs. No parameters.");
538259ca6d1SGowrishankar Muthukrishnan 
539259ca6d1SGowrishankar Muthukrishnan 	rte_telemetry_register_cmd("/security/cryptodev/sec_caps",
540259ca6d1SGowrishankar Muthukrishnan 		security_handle_cryptodev_sec_caps,
541259ca6d1SGowrishankar Muthukrishnan 		"Returns security capabilities for a cryptodev. Parameters: int dev_id");
542259ca6d1SGowrishankar Muthukrishnan 
543259ca6d1SGowrishankar Muthukrishnan 	rte_telemetry_register_cmd("/security/cryptodev/crypto_caps",
544259ca6d1SGowrishankar Muthukrishnan 		security_handle_cryptodev_crypto_caps,
545259ca6d1SGowrishankar Muthukrishnan 		"Returns crypto capabilities for a security capability. Parameters: int dev_id, sec_cap_id");
546259ca6d1SGowrishankar Muthukrishnan }
547