1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2017 NXP. 3 * Copyright(c) 2017 Intel Corporation. 4 * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved 5 */ 6 7 #include <rte_malloc.h> 8 #include <rte_dev.h> 9 #include "rte_compat.h" 10 #include "rte_security.h" 11 #include "rte_security_driver.h" 12 13 /* Macro to check for invalid pointers */ 14 #define RTE_PTR_OR_ERR_RET(ptr, retval) do { \ 15 if ((ptr) == NULL) \ 16 return retval; \ 17 } while (0) 18 19 /* Macro to check for invalid pointers chains */ 20 #define RTE_PTR_CHAIN3_OR_ERR_RET(p1, p2, p3, retval, last_retval) do { \ 21 RTE_PTR_OR_ERR_RET(p1, retval); \ 22 RTE_PTR_OR_ERR_RET(p1->p2, retval); \ 23 RTE_PTR_OR_ERR_RET(p1->p2->p3, last_retval); \ 24 } while (0) 25 26 #define RTE_SECURITY_DYNFIELD_NAME "rte_security_dynfield_metadata" 27 int rte_security_dynfield_offset = -1; 28 29 int 30 rte_security_dynfield_register(void) 31 { 32 static const struct rte_mbuf_dynfield dynfield_desc = { 33 .name = RTE_SECURITY_DYNFIELD_NAME, 34 .size = sizeof(rte_security_dynfield_t), 35 .align = __alignof__(rte_security_dynfield_t), 36 }; 37 rte_security_dynfield_offset = 38 rte_mbuf_dynfield_register(&dynfield_desc); 39 return rte_security_dynfield_offset; 40 } 41 42 struct rte_security_session * 43 rte_security_session_create(struct rte_security_ctx *instance, 44 struct rte_security_session_conf *conf, 45 struct rte_mempool *mp, 46 struct rte_mempool *priv_mp) 47 { 48 struct rte_security_session *sess = NULL; 49 50 RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_create, NULL, NULL); 51 RTE_PTR_OR_ERR_RET(conf, NULL); 52 RTE_PTR_OR_ERR_RET(mp, NULL); 53 RTE_PTR_OR_ERR_RET(priv_mp, NULL); 54 55 if (rte_mempool_get(mp, (void **)&sess)) 56 return NULL; 57 58 if (instance->ops->session_create(instance->device, conf, 59 sess, priv_mp)) { 60 rte_mempool_put(mp, (void *)sess); 61 return NULL; 62 } 63 instance->sess_cnt++; 64 65 return sess; 66 } 67 68 int 69 rte_security_session_update(struct rte_security_ctx *instance, 70 struct rte_security_session *sess, 71 struct rte_security_session_conf *conf) 72 { 73 RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_update, -EINVAL, 74 -ENOTSUP); 75 RTE_PTR_OR_ERR_RET(sess, -EINVAL); 76 RTE_PTR_OR_ERR_RET(conf, -EINVAL); 77 78 return instance->ops->session_update(instance->device, sess, conf); 79 } 80 81 unsigned int 82 rte_security_session_get_size(struct rte_security_ctx *instance) 83 { 84 RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_get_size, 0, 0); 85 86 return instance->ops->session_get_size(instance->device); 87 } 88 89 int 90 rte_security_session_stats_get(struct rte_security_ctx *instance, 91 struct rte_security_session *sess, 92 struct rte_security_stats *stats) 93 { 94 RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_stats_get, -EINVAL, 95 -ENOTSUP); 96 /* Parameter sess can be NULL in case of getting global statistics. */ 97 RTE_PTR_OR_ERR_RET(stats, -EINVAL); 98 99 return instance->ops->session_stats_get(instance->device, sess, stats); 100 } 101 102 int 103 rte_security_session_destroy(struct rte_security_ctx *instance, 104 struct rte_security_session *sess) 105 { 106 int ret; 107 108 RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, session_destroy, -EINVAL, 109 -ENOTSUP); 110 RTE_PTR_OR_ERR_RET(sess, -EINVAL); 111 112 ret = instance->ops->session_destroy(instance->device, sess); 113 if (ret != 0) 114 return ret; 115 116 rte_mempool_put(rte_mempool_from_obj(sess), (void *)sess); 117 118 if (instance->sess_cnt) 119 instance->sess_cnt--; 120 121 return 0; 122 } 123 124 int 125 __rte_security_set_pkt_metadata(struct rte_security_ctx *instance, 126 struct rte_security_session *sess, 127 struct rte_mbuf *m, void *params) 128 { 129 #ifdef RTE_DEBUG 130 RTE_PTR_OR_ERR_RET(sess, -EINVAL); 131 RTE_PTR_OR_ERR_RET(instance, -EINVAL); 132 RTE_PTR_OR_ERR_RET(instance->ops, -EINVAL); 133 #endif 134 RTE_FUNC_PTR_OR_ERR_RET(*instance->ops->set_pkt_metadata, -ENOTSUP); 135 return instance->ops->set_pkt_metadata(instance->device, 136 sess, m, params); 137 } 138 139 void * 140 __rte_security_get_userdata(struct rte_security_ctx *instance, uint64_t md) 141 { 142 void *userdata = NULL; 143 144 #ifdef RTE_DEBUG 145 RTE_PTR_OR_ERR_RET(instance, NULL); 146 RTE_PTR_OR_ERR_RET(instance->ops, NULL); 147 #endif 148 RTE_FUNC_PTR_OR_ERR_RET(*instance->ops->get_userdata, NULL); 149 if (instance->ops->get_userdata(instance->device, md, &userdata)) 150 return NULL; 151 152 return userdata; 153 } 154 155 const struct rte_security_capability * 156 rte_security_capabilities_get(struct rte_security_ctx *instance) 157 { 158 RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, capabilities_get, NULL, NULL); 159 160 return instance->ops->capabilities_get(instance->device); 161 } 162 163 const struct rte_security_capability * 164 rte_security_capability_get(struct rte_security_ctx *instance, 165 struct rte_security_capability_idx *idx) 166 { 167 const struct rte_security_capability *capabilities; 168 const struct rte_security_capability *capability; 169 uint16_t i = 0; 170 171 RTE_PTR_CHAIN3_OR_ERR_RET(instance, ops, capabilities_get, NULL, NULL); 172 RTE_PTR_OR_ERR_RET(idx, NULL); 173 174 capabilities = instance->ops->capabilities_get(instance->device); 175 176 if (capabilities == NULL) 177 return NULL; 178 179 while ((capability = &capabilities[i++])->action 180 != RTE_SECURITY_ACTION_TYPE_NONE) { 181 if (capability->action == idx->action && 182 capability->protocol == idx->protocol) { 183 if (idx->protocol == RTE_SECURITY_PROTOCOL_IPSEC) { 184 if (capability->ipsec.proto == 185 idx->ipsec.proto && 186 capability->ipsec.mode == 187 idx->ipsec.mode && 188 capability->ipsec.direction == 189 idx->ipsec.direction) 190 return capability; 191 } else if (idx->protocol == RTE_SECURITY_PROTOCOL_PDCP) { 192 if (capability->pdcp.domain == 193 idx->pdcp.domain) 194 return capability; 195 } else if (idx->protocol == 196 RTE_SECURITY_PROTOCOL_DOCSIS) { 197 if (capability->docsis.direction == 198 idx->docsis.direction) 199 return capability; 200 } 201 } 202 } 203 204 return NULL; 205 } 206