1
2
3
4
5
6#include <rte_crypto.h>
7#include <rte_crypto_sym.h>
8#include <rte_log.h>
9
10#include "bcmfs_logs.h"
11#include "bcmfs_sym_defs.h"
12#include "bcmfs_sym_pmd.h"
13#include "bcmfs_sym_session.h"
14
15
16static enum bcmfs_sym_chain_order
17crypto_get_chain_order(const struct rte_crypto_sym_xform *xform)
18{
19 enum bcmfs_sym_chain_order res = BCMFS_SYM_CHAIN_NOT_SUPPORTED;
20
21 if (xform != NULL) {
22 if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
23 res = BCMFS_SYM_CHAIN_AEAD;
24
25 if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
26 if (xform->next == NULL)
27 res = BCMFS_SYM_CHAIN_ONLY_AUTH;
28 else if (xform->next->type ==
29 RTE_CRYPTO_SYM_XFORM_CIPHER)
30 res = BCMFS_SYM_CHAIN_AUTH_CIPHER;
31 }
32 if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
33 if (xform->next == NULL)
34 res = BCMFS_SYM_CHAIN_ONLY_CIPHER;
35 else if (xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
36 res = BCMFS_SYM_CHAIN_CIPHER_AUTH;
37 }
38 }
39
40 return res;
41}
42
43
44static void
45get_key(const uint8_t *input_key, int keylen, uint8_t *session_key)
46{
47 memcpy(session_key, input_key, keylen);
48}
49
50
51static int
52crypto_set_session_cipher_parameters(struct bcmfs_sym_session *sess,
53 const struct rte_crypto_cipher_xform *cipher_xform)
54{
55 if (cipher_xform->key.length > BCMFS_MAX_KEY_SIZE) {
56 BCMFS_DP_LOG(ERR, "key length not supported");
57 return -EINVAL;
58 }
59
60 sess->cipher.key.length = cipher_xform->key.length;
61 sess->cipher.iv.offset = cipher_xform->iv.offset;
62 sess->cipher.iv.length = cipher_xform->iv.length;
63 sess->cipher.op = cipher_xform->op;
64 sess->cipher.algo = cipher_xform->algo;
65
66 get_key(cipher_xform->key.data,
67 sess->cipher.key.length,
68 sess->cipher.key.data);
69
70 return 0;
71}
72
73
74static int
75crypto_set_session_auth_parameters(struct bcmfs_sym_session *sess,
76 const struct rte_crypto_auth_xform *auth_xform)
77{
78 if (auth_xform->key.length > BCMFS_MAX_KEY_SIZE) {
79 BCMFS_DP_LOG(ERR, "key length not supported");
80 return -EINVAL;
81 }
82
83 sess->auth.op = auth_xform->op;
84 sess->auth.key.length = auth_xform->key.length;
85 sess->auth.digest_length = auth_xform->digest_length;
86 sess->auth.iv.length = auth_xform->iv.length;
87 sess->auth.iv.offset = auth_xform->iv.offset;
88 sess->auth.algo = auth_xform->algo;
89
90 get_key(auth_xform->key.data,
91 auth_xform->key.length,
92 sess->auth.key.data);
93
94 return 0;
95}
96
97
98static int
99crypto_set_session_aead_parameters(struct bcmfs_sym_session *sess,
100 const struct rte_crypto_sym_xform *aead_xform)
101{
102 if (aead_xform->aead.key.length > BCMFS_MAX_KEY_SIZE) {
103 BCMFS_DP_LOG(ERR, "key length not supported");
104 return -EINVAL;
105 }
106
107 sess->aead.iv.offset = aead_xform->aead.iv.offset;
108 sess->aead.iv.length = aead_xform->aead.iv.length;
109 sess->aead.aad_length = aead_xform->aead.aad_length;
110 sess->aead.key.length = aead_xform->aead.key.length;
111 sess->aead.digest_length = aead_xform->aead.digest_length;
112 sess->aead.op = aead_xform->aead.op;
113 sess->aead.algo = aead_xform->aead.algo;
114
115 get_key(aead_xform->aead.key.data,
116 aead_xform->aead.key.length,
117 sess->aead.key.data);
118
119 return 0;
120}
121
122static struct rte_crypto_auth_xform *
123crypto_get_auth_xform(struct rte_crypto_sym_xform *xform)
124{
125 do {
126 if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH)
127 return &xform->auth;
128
129 xform = xform->next;
130 } while (xform);
131
132 return NULL;
133}
134
135static struct rte_crypto_cipher_xform *
136crypto_get_cipher_xform(struct rte_crypto_sym_xform *xform)
137{
138 do {
139 if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
140 return &xform->cipher;
141
142 xform = xform->next;
143 } while (xform);
144
145 return NULL;
146}
147
148
149static int
150crypto_set_session_parameters(struct bcmfs_sym_session *sess,
151 struct rte_crypto_sym_xform *xform)
152{
153 int rc = 0;
154 struct rte_crypto_cipher_xform *cipher_xform =
155 crypto_get_cipher_xform(xform);
156 struct rte_crypto_auth_xform *auth_xform =
157 crypto_get_auth_xform(xform);
158
159 sess->chain_order = crypto_get_chain_order(xform);
160
161 switch (sess->chain_order) {
162 case BCMFS_SYM_CHAIN_ONLY_CIPHER:
163 if (crypto_set_session_cipher_parameters(sess, cipher_xform))
164 rc = -EINVAL;
165 break;
166 case BCMFS_SYM_CHAIN_ONLY_AUTH:
167 if (crypto_set_session_auth_parameters(sess, auth_xform))
168 rc = -EINVAL;
169 break;
170 case BCMFS_SYM_CHAIN_AUTH_CIPHER:
171 sess->cipher_first = false;
172 if (crypto_set_session_auth_parameters(sess, auth_xform)) {
173 rc = -EINVAL;
174 goto error;
175 }
176
177 if (crypto_set_session_cipher_parameters(sess, cipher_xform))
178 rc = -EINVAL;
179 break;
180 case BCMFS_SYM_CHAIN_CIPHER_AUTH:
181 sess->cipher_first = true;
182 if (crypto_set_session_auth_parameters(sess, auth_xform)) {
183 rc = -EINVAL;
184 goto error;
185 }
186
187 if (crypto_set_session_cipher_parameters(sess, cipher_xform))
188 rc = -EINVAL;
189 break;
190 case BCMFS_SYM_CHAIN_AEAD:
191 if (crypto_set_session_aead_parameters(sess, xform))
192 rc = -EINVAL;
193 break;
194 default:
195 BCMFS_DP_LOG(ERR, "Invalid chain order\n");
196 rc = -EINVAL;
197 break;
198 }
199
200error:
201 return rc;
202}
203
204struct bcmfs_sym_session *
205bcmfs_sym_get_session(struct rte_crypto_op *op)
206{
207 struct bcmfs_sym_session *sess = NULL;
208
209 if (unlikely(op->sess_type == RTE_CRYPTO_OP_SESSIONLESS)) {
210 BCMFS_DP_LOG(ERR, "operations op(%p) is sessionless", op);
211 } else if (likely(op->sym->session != NULL)) {
212
213 sess = (struct bcmfs_sym_session *)
214 get_sym_session_private_data(op->sym->session,
215 cryptodev_bcmfs_driver_id);
216 }
217
218 if (sess == NULL)
219 op->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
220
221 return sess;
222}
223
224int
225bcmfs_sym_session_configure(struct rte_cryptodev *dev,
226 struct rte_crypto_sym_xform *xform,
227 struct rte_cryptodev_sym_session *sess,
228 struct rte_mempool *mempool)
229{
230 void *sess_private_data;
231 int ret;
232
233 if (unlikely(sess == NULL)) {
234 BCMFS_DP_LOG(ERR, "Invalid session struct");
235 return -EINVAL;
236 }
237
238 if (rte_mempool_get(mempool, &sess_private_data)) {
239 BCMFS_DP_LOG(ERR,
240 "Couldn't get object from session mempool");
241 return -ENOMEM;
242 }
243
244 ret = crypto_set_session_parameters(sess_private_data, xform);
245
246 if (ret != 0) {
247 BCMFS_DP_LOG(ERR, "Failed configure session parameters");
248
249 rte_mempool_put(mempool, sess_private_data);
250 return ret;
251 }
252
253 set_sym_session_private_data(sess, dev->driver_id,
254 sess_private_data);
255
256 return 0;
257}
258
259
260void
261bcmfs_sym_session_clear(struct rte_cryptodev *dev,
262 struct rte_cryptodev_sym_session *sess)
263{
264 uint8_t index = dev->driver_id;
265 void *sess_priv = get_sym_session_private_data(sess, index);
266
267 if (sess_priv) {
268 struct rte_mempool *sess_mp;
269
270 memset(sess_priv, 0, sizeof(struct bcmfs_sym_session));
271 sess_mp = rte_mempool_from_obj(sess_priv);
272
273 set_sym_session_private_data(sess, index, NULL);
274 rte_mempool_put(sess_mp, sess_priv);
275 }
276}
277
278unsigned int
279bcmfs_sym_session_get_private_size(struct rte_cryptodev *dev __rte_unused)
280{
281 return sizeof(struct bcmfs_sym_session);
282}
283