Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #ifndef _CNXK_SE_H_
6 : : #define _CNXK_SE_H_
7 : : #include <stdbool.h>
8 : :
9 : : #include <rte_cryptodev.h>
10 : :
11 : : #include "cnxk_cryptodev.h"
12 : : #include "cnxk_cryptodev_ops.h"
13 : : #include "cnxk_sg.h"
14 : :
15 : : #define SRC_IOV_SIZE \
16 : : (sizeof(struct roc_se_iov_ptr) + (sizeof(struct roc_se_buf_ptr) * ROC_MAX_SG_CNT))
17 : : #define DST_IOV_SIZE \
18 : : (sizeof(struct roc_se_iov_ptr) + (sizeof(struct roc_se_buf_ptr) * ROC_MAX_SG_CNT))
19 : :
20 : : #define META_PKT_CTL_ENABLE 1
21 : : #define META_SIZE_DIVISOR 32
22 : :
23 : : enum cpt_dp_thread_type {
24 : : CPT_DP_THREAD_TYPE_FC_CHAIN = 0x1,
25 : : CPT_DP_THREAD_TYPE_FC_AEAD,
26 : : CPT_DP_THREAD_TYPE_PDCP,
27 : : CPT_DP_THREAD_TYPE_PDCP_CHAIN,
28 : : CPT_DP_THREAD_TYPE_KASUMI,
29 : : CPT_DP_THREAD_TYPE_SM,
30 : : CPT_DP_THREAD_AUTH_ONLY,
31 : : CPT_DP_THREAD_GENERIC,
32 : : CPT_DP_THREAD_TYPE_PT,
33 : : };
34 : :
35 : : #define SYM_SESS_SIZE sizeof(struct rte_cryptodev_sym_session)
36 : :
37 : : struct __rte_aligned(ROC_ALIGN) cnxk_se_sess {
38 : : uint8_t rte_sess[SYM_SESS_SIZE];
39 : :
40 : : uint8_t aes_gcm : 1;
41 : : uint8_t aes_ccm : 1;
42 : : uint8_t aes_ctr : 1;
43 : : uint8_t chacha_poly : 1;
44 : : uint8_t is_null : 1;
45 : : uint8_t is_gmac : 1;
46 : : uint8_t chained_op : 1;
47 : : uint8_t auth_first : 1;
48 : : uint8_t aes_ctr_eea2 : 1;
49 : : uint8_t is_sha3 : 1;
50 : : uint8_t short_iv : 1;
51 : : uint8_t is_sm3 : 1;
52 : : uint8_t passthrough : 1;
53 : : uint8_t is_sm4 : 1;
54 : : uint8_t cipher_only : 1;
55 : : uint8_t rsvd : 1;
56 : : uint8_t cpt_op : 4;
57 : : uint8_t zsk_flag : 4;
58 : : uint8_t zs_cipher : 4;
59 : : uint8_t zs_auth : 4;
60 : : uint8_t dp_thr_type;
61 : : uint8_t mac_len;
62 : : uint8_t iv_length;
63 : : uint8_t auth_iv_length;
64 : : uint16_t aad_length;
65 : : uint16_t iv_offset;
66 : : uint16_t auth_iv_offset;
67 : : uint32_t salt;
68 : : uint64_t cpt_inst_w7;
69 : : uint64_t cpt_inst_w2;
70 : : struct cnxk_cpt_qp *qp;
71 : : struct roc_se_ctx *roc_se_ctx;
72 : : struct roc_cpt_lf *lf;
73 : : };
74 : :
75 : : struct cnxk_sym_dp_ctx {
76 : : struct cnxk_se_sess *sess;
77 : : };
78 : :
79 : : struct cnxk_iov {
80 : : char src[SRC_IOV_SIZE];
81 : : char dst[SRC_IOV_SIZE];
82 : : void *iv_buf;
83 : : void *aad_buf;
84 : : void *mac_buf;
85 : : uint16_t c_head;
86 : : uint16_t c_tail;
87 : : uint16_t a_head;
88 : : uint16_t a_tail;
89 : : int data_len;
90 : : };
91 : :
92 : : static __rte_always_inline int fill_sess_gmac(struct rte_crypto_sym_xform *xform,
93 : : struct cnxk_se_sess *sess);
94 : :
95 : : static inline void
96 : 0 : cpt_pack_iv(uint8_t *iv_src, uint8_t *iv_dst)
97 : : {
98 : : /* pack the first 8 bytes of IV to 6 bytes.
99 : : * discard the 2 MSB bits of each byte
100 : : */
101 : 0 : iv_dst[0] = (((iv_src[0] & 0x3f) << 2) | ((iv_src[1] >> 4) & 0x3));
102 : 0 : iv_dst[1] = (((iv_src[1] & 0xf) << 4) | ((iv_src[2] >> 2) & 0xf));
103 : 0 : iv_dst[2] = (((iv_src[2] & 0x3) << 6) | (iv_src[3] & 0x3f));
104 : :
105 : 0 : iv_dst[3] = (((iv_src[4] & 0x3f) << 2) | ((iv_src[5] >> 4) & 0x3));
106 : 0 : iv_dst[4] = (((iv_src[5] & 0xf) << 4) | ((iv_src[6] >> 2) & 0xf));
107 : 0 : iv_dst[5] = (((iv_src[6] & 0x3) << 6) | (iv_src[7] & 0x3f));
108 : 0 : }
109 : :
110 : : static inline void
111 : 0 : pdcp_iv_copy(uint8_t *iv_d, const uint8_t *iv_s, const uint8_t pdcp_alg_type, const bool pack_iv)
112 : : {
113 : : const uint32_t *iv_s_temp;
114 : : uint32_t iv_temp[4];
115 : : int j;
116 : :
117 [ # # ]: 0 : if (unlikely(iv_s == NULL)) {
118 : : memset(iv_d, 0, 16);
119 : 0 : return;
120 : : }
121 : :
122 [ # # ]: 0 : if (pdcp_alg_type == ROC_SE_PDCP_ALG_TYPE_SNOW3G) {
123 : : /*
124 : : * DPDK seems to provide it in form of IV3 IV2 IV1 IV0
125 : : * and BigEndian, MC needs it as IV0 IV1 IV2 IV3
126 : : */
127 : :
128 : : iv_s_temp = (const uint32_t *)iv_s;
129 : :
130 [ # # ]: 0 : for (j = 0; j < 4; j++)
131 : 0 : iv_temp[j] = iv_s_temp[3 - j];
132 : : memcpy(iv_d, iv_temp, 16);
133 : 0 : } else if ((pdcp_alg_type == ROC_SE_PDCP_ALG_TYPE_ZUC) ||
134 [ # # ]: 0 : pdcp_alg_type == ROC_SE_PDCP_ALG_TYPE_AES_CTR) {
135 : : memcpy(iv_d, iv_s, 16);
136 [ # # ]: 0 : if (pack_iv) {
137 : : uint8_t iv_d23, iv_d24;
138 : :
139 : : /* Save last two bytes as only 23B IV space is available */
140 : 0 : iv_d23 = iv_d[23];
141 : 0 : iv_d24 = iv_d[24];
142 : :
143 : : /* Copy remaining part of IV */
144 : 0 : memcpy(iv_d + 16, iv_s + 16, 25 - 16);
145 : :
146 : : /* Swap IV */
147 : : roc_se_zuc_bytes_swap(iv_d, 25);
148 : :
149 : : /* Pack IV */
150 : 0 : cpt_pack_iv(iv_d, iv_d);
151 : :
152 : : /* Move IV */
153 [ # # ]: 0 : for (j = 6; j < 23; j++)
154 : 0 : iv_d[j] = iv_d[j + 2];
155 : :
156 : 0 : iv_d[23] = iv_d23;
157 : 0 : iv_d[24] = iv_d24;
158 : : }
159 : : }
160 : : }
161 : :
162 : : /*
163 : : * Digest immediately at the end of the data is the best case. Switch to SG if
164 : : * that cannot be ensured.
165 : : */
166 : : static inline void
167 : 0 : cpt_digest_buf_lb_check(const struct cnxk_se_sess *sess, struct rte_mbuf *m,
168 : : struct roc_se_fc_params *fc_params, uint32_t *flags,
169 : : struct rte_crypto_sym_op *sym_op, bool *inplace, uint32_t a_data_off,
170 : : uint32_t a_data_len, uint32_t c_data_off, uint32_t c_data_len,
171 : : const bool is_pdcp_chain)
172 : : {
173 : 0 : const uint32_t auth_end = a_data_off + a_data_len;
174 : : uint32_t mc_hash_off;
175 : :
176 : : /* PDCP_CHAIN only supports auth_first */
177 : :
178 [ # # # # ]: 0 : if (is_pdcp_chain || sess->auth_first)
179 : : mc_hash_off = auth_end;
180 : : else
181 : 0 : mc_hash_off = RTE_MAX(c_data_off + c_data_len, auth_end);
182 : :
183 : : /* Digest immediately following data is best case */
184 : :
185 [ # # ]: 0 : if (unlikely(rte_pktmbuf_mtod_offset(m, uint8_t *, mc_hash_off) !=
186 : : sym_op->auth.digest.data)) {
187 : 0 : *flags |= ROC_SE_VALID_MAC_BUF;
188 : 0 : fc_params->mac_buf.size = sess->mac_len;
189 : 0 : fc_params->mac_buf.vaddr = sym_op->auth.digest.data;
190 : 0 : *inplace = false;
191 : : }
192 : 0 : }
193 : :
194 : : static inline struct rte_mbuf *
195 : 0 : cpt_m_dst_get(uint8_t cpt_op, struct rte_mbuf *m_src, struct rte_mbuf *m_dst)
196 : : {
197 [ # # # # ]: 0 : if (m_dst != NULL && (cpt_op & ROC_SE_OP_ENCODE))
198 : : return m_dst;
199 : : else
200 : 0 : return m_src;
201 : : }
202 : :
203 : : static __rte_always_inline int
204 : : cpt_mac_len_verify(struct rte_crypto_auth_xform *auth)
205 : : {
206 : 0 : uint16_t mac_len = auth->digest_length;
207 : : int ret;
208 : :
209 [ # # # # ]: 0 : if ((auth->algo != RTE_CRYPTO_AUTH_NULL) && (mac_len == 0))
210 : : return -1;
211 : :
212 [ # # # # : 0 : switch (auth->algo) {
# # # # #
# ]
213 : 0 : case RTE_CRYPTO_AUTH_MD5:
214 : : case RTE_CRYPTO_AUTH_MD5_HMAC:
215 [ # # ]: 0 : ret = (mac_len <= 16) ? 0 : -1;
216 : : break;
217 : 0 : case RTE_CRYPTO_AUTH_SHA1:
218 : : case RTE_CRYPTO_AUTH_SHA1_HMAC:
219 [ # # ]: 0 : ret = (mac_len <= 20) ? 0 : -1;
220 : : break;
221 : 0 : case RTE_CRYPTO_AUTH_SHA224:
222 : : case RTE_CRYPTO_AUTH_SHA224_HMAC:
223 : : case RTE_CRYPTO_AUTH_SHA3_224:
224 : : case RTE_CRYPTO_AUTH_SHA3_224_HMAC:
225 [ # # ]: 0 : ret = (mac_len <= 28) ? 0 : -1;
226 : : break;
227 : 0 : case RTE_CRYPTO_AUTH_SHA256:
228 : : case RTE_CRYPTO_AUTH_SHA256_HMAC:
229 : : case RTE_CRYPTO_AUTH_SHA3_256:
230 : : case RTE_CRYPTO_AUTH_SHA3_256_HMAC:
231 [ # # ]: 0 : ret = (mac_len <= 32) ? 0 : -1;
232 : : break;
233 : 0 : case RTE_CRYPTO_AUTH_SHA384:
234 : : case RTE_CRYPTO_AUTH_SHA384_HMAC:
235 : : case RTE_CRYPTO_AUTH_SHA3_384:
236 : : case RTE_CRYPTO_AUTH_SHA3_384_HMAC:
237 [ # # ]: 0 : ret = (mac_len <= 48) ? 0 : -1;
238 : : break;
239 : 0 : case RTE_CRYPTO_AUTH_SHA512:
240 : : case RTE_CRYPTO_AUTH_SHA512_HMAC:
241 : : case RTE_CRYPTO_AUTH_SHA3_512:
242 : : case RTE_CRYPTO_AUTH_SHA3_512_HMAC:
243 [ # # ]: 0 : ret = (mac_len <= 64) ? 0 : -1;
244 : : break;
245 : : /* SHAKE itself doesn't have limitation of digest length,
246 : : * but in microcode size of length field is limited to 8 bits
247 : : */
248 : 0 : case RTE_CRYPTO_AUTH_SHAKE_128:
249 : : case RTE_CRYPTO_AUTH_SHAKE_256:
250 [ # # ]: 0 : ret = (mac_len <= UINT8_MAX) ? 0 : -1;
251 : : break;
252 : 0 : case RTE_CRYPTO_AUTH_SM3:
253 [ # # ]: 0 : ret = (mac_len <= 32) ? 0 : -1;
254 : : break;
255 : : case RTE_CRYPTO_AUTH_NULL:
256 : : ret = 0;
257 : : break;
258 : : default:
259 : : ret = -1;
260 : : }
261 : :
262 : : return ret;
263 : : }
264 : :
265 : : static __rte_always_inline int
266 : : sg_inst_prep(struct roc_se_fc_params *params, struct cpt_inst_s *inst, uint64_t offset_ctrl,
267 : : const uint8_t *iv_s, int iv_len, const bool pack_iv, uint8_t pdcp_alg_type,
268 : : int32_t inputlen, int32_t outputlen, uint32_t passthrough_len, uint32_t req_flags,
269 : : int pdcp_flag, int decrypt)
270 : : {
271 : : struct roc_sglist_comp *gather_comp, *scatter_comp;
272 : 0 : void *m_vaddr = params->meta_buf.vaddr;
273 : : struct roc_se_buf_ptr *aad_buf = NULL;
274 : : uint32_t mac_len = 0, aad_len = 0;
275 : : struct roc_se_ctx *se_ctx;
276 : : uint32_t i, g_size_bytes;
277 : : int zsk_flags, ret = 0;
278 : : uint64_t *offset_vaddr;
279 : : uint32_t s_size_bytes;
280 : : uint8_t *in_buffer;
281 : : uint32_t size;
282 : : uint8_t *iv_d;
283 : :
284 : : se_ctx = params->ctx;
285 : 0 : zsk_flags = se_ctx->zsk_flags;
286 : 0 : mac_len = se_ctx->mac_len;
287 : :
288 : 0 : if (unlikely(req_flags & ROC_SE_VALID_AAD_BUF)) {
289 : : /* We don't support both AAD and auth data separately */
290 : : aad_len = params->aad_buf.size;
291 : : aad_buf = ¶ms->aad_buf;
292 : : }
293 : :
294 : : /* save space for iv */
295 : : offset_vaddr = m_vaddr;
296 : :
297 : 0 : m_vaddr = (uint8_t *)m_vaddr + ROC_SE_OFF_CTRL_LEN + RTE_ALIGN_CEIL(iv_len, 8);
298 : :
299 : 0 : inst->w4.s.opcode_major |= (uint64_t)ROC_DMA_MODE_SG;
300 : :
301 : : /* iv offset is 0 */
302 : 0 : *offset_vaddr = offset_ctrl;
303 : :
304 [ # # # # : 0 : iv_d = ((uint8_t *)offset_vaddr + ROC_SE_OFF_CTRL_LEN);
# # # # #
# # # ]
305 : :
306 : : if (pdcp_flag) {
307 : 0 : if (likely(iv_len)) {
308 [ # # # # : 0 : if (zsk_flags == 0x1)
# # # # ]
309 : 0 : pdcp_iv_copy(iv_d + params->pdcp_iv_offset, iv_s, pdcp_alg_type,
310 : : pack_iv);
311 : : else
312 : 0 : pdcp_iv_copy(iv_d, iv_s, pdcp_alg_type, pack_iv);
313 : : }
314 : : } else {
315 [ # # # # : 0 : if (likely(iv_len))
# # # # #
# # # ]
316 : 0 : memcpy(iv_d, iv_s, iv_len);
317 : : }
318 : :
319 : : /* DPTR has SG list */
320 : :
321 : : /* TODO Add error check if space will be sufficient */
322 : 0 : gather_comp = (struct roc_sglist_comp *)((uint8_t *)m_vaddr + 8);
323 : :
324 : : /*
325 : : * Input Gather List
326 : : */
327 : : i = 0;
328 : :
329 : : /* Offset control word followed by iv */
330 : :
331 [ # # # # : 0 : i = fill_sg_comp(gather_comp, i, (uint64_t)offset_vaddr, ROC_SE_OFF_CTRL_LEN + iv_len);
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
332 : :
333 : : /* Add input data */
334 [ # # # # : 0 : if (decrypt && (req_flags & ROC_SE_VALID_MAC_BUF)) {
# # # # #
# # # ]
335 : 0 : size = inputlen - iv_len - mac_len;
336 [ # # # # : 0 : if (likely(size)) {
# # # # #
# # # ]
337 [ # # # # : 0 : uint32_t aad_offset = aad_len ? passthrough_len : 0;
# # ]
338 : : /* input data only */
339 [ # # # # : 0 : if (unlikely(req_flags & ROC_SE_SINGLE_BUF_INPLACE)) {
# # # # ]
340 : : i = fill_sg_comp_from_buf_min(gather_comp, i, params->bufs, &size);
341 : : } else {
342 [ # # # # ]: 0 : i = fill_sg_comp_from_iov(gather_comp, i, params->src_iov, 0, &size,
343 : : aad_buf, aad_offset);
344 : : }
345 [ # # # # : 0 : if (unlikely(size)) {
# # # # #
# # # ]
346 : 0 : plt_dp_err("Insufficient buffer"
347 : : " space, size %d needed",
348 : : size);
349 : 0 : return -1;
350 : : }
351 : : }
352 : :
353 [ # # # # : 0 : if (mac_len)
# # # # #
# # # ]
354 : : i = fill_sg_comp_from_buf(gather_comp, i, ¶ms->mac_buf);
355 : : } else {
356 : : /* input data */
357 : 0 : size = inputlen - iv_len;
358 [ # # # # : 0 : if (size) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
359 [ # # # # : 0 : uint32_t aad_offset = aad_len ? passthrough_len : 0;
# # # # #
# # # ]
360 [ # # # # : 0 : if (unlikely(req_flags & ROC_SE_SINGLE_BUF_INPLACE)) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
361 : : i = fill_sg_comp_from_buf_min(gather_comp, i, params->bufs, &size);
362 : : } else {
363 [ # # # # : 0 : i = fill_sg_comp_from_iov(gather_comp, i, params->src_iov, 0, &size,
# # # # ]
364 : : aad_buf, aad_offset);
365 : : }
366 [ # # # # : 0 : if (unlikely(size)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
367 : 0 : plt_dp_err("Insufficient buffer space,"
368 : : " size %d needed",
369 : : size);
370 : 0 : return -1;
371 : : }
372 : : }
373 : : }
374 : :
375 : : in_buffer = m_vaddr;
376 : :
377 : 0 : ((uint16_t *)in_buffer)[0] = 0;
378 : 0 : ((uint16_t *)in_buffer)[1] = 0;
379 [ # # # # : 0 : ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
380 : :
381 : 0 : g_size_bytes = ((i + 3) / 4) * sizeof(struct roc_sglist_comp);
382 : : /*
383 : : * Output Scatter List
384 : : */
385 : :
386 : : i = 0;
387 : 0 : scatter_comp = (struct roc_sglist_comp *)((uint8_t *)gather_comp + g_size_bytes);
388 : :
389 [ # # # # : 0 : if ((zsk_flags == 0x1) && (se_ctx->fc_type == ROC_SE_KASUMI)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
390 : : /* IV in SLIST only for EEA3 & UEA2 or for F8 */
391 : : iv_len = 0;
392 : : }
393 : :
394 [ # # # # : 0 : if (iv_len) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
395 [ # # # # : 0 : i = fill_sg_comp(scatter_comp, i, (uint64_t)offset_vaddr + ROC_SE_OFF_CTRL_LEN,
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # ]
396 : : iv_len);
397 : : }
398 : :
399 : : /* Add output data */
400 [ # # # # : 0 : if ((!decrypt) && (req_flags & ROC_SE_VALID_MAC_BUF)) {
# # # # #
# # # # #
# # ]
401 : 0 : size = outputlen - iv_len - mac_len;
402 [ # # # # : 0 : if (size) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
403 : :
404 [ # # # # : 0 : uint32_t aad_offset = aad_len ? passthrough_len : 0;
# # ]
405 : :
406 [ # # # # : 0 : if (unlikely(req_flags & ROC_SE_SINGLE_BUF_INPLACE)) {
# # # # ]
407 : : i = fill_sg_comp_from_buf_min(scatter_comp, i, params->bufs, &size);
408 : : } else {
409 [ # # # # ]: 0 : i = fill_sg_comp_from_iov(scatter_comp, i, params->dst_iov, 0,
410 : : &size, aad_buf, aad_offset);
411 : : }
412 [ # # # # : 0 : if (unlikely(size)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
413 : 0 : plt_dp_err("Insufficient buffer space,"
414 : : " size %d needed",
415 : : size);
416 : 0 : return -1;
417 : : }
418 : : }
419 : :
420 : : /* mac data */
421 [ # # # # : 0 : if (mac_len)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
422 : : i = fill_sg_comp_from_buf(scatter_comp, i, ¶ms->mac_buf);
423 : : } else {
424 : : /* Output including mac */
425 : 0 : size = outputlen - iv_len;
426 [ # # # # : 0 : if (size) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
427 [ # # # # : 0 : uint32_t aad_offset = aad_len ? passthrough_len : 0;
# # # # #
# # # ]
428 : :
429 [ # # # # : 0 : if (unlikely(req_flags & ROC_SE_SINGLE_BUF_INPLACE)) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
430 : : i = fill_sg_comp_from_buf_min(scatter_comp, i, params->bufs, &size);
431 : : } else {
432 [ # # # # : 0 : i = fill_sg_comp_from_iov(scatter_comp, i, params->dst_iov, 0,
# # # # ]
433 : : &size, aad_buf, aad_offset);
434 : : }
435 : :
436 [ # # # # : 0 : if (unlikely(size)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
437 : 0 : plt_dp_err("Insufficient buffer space,"
438 : : " size %d needed",
439 : : size);
440 : 0 : return -1;
441 : : }
442 : : }
443 : : }
444 [ # # # # : 0 : ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
445 : 0 : s_size_bytes = ((i + 3) / 4) * sizeof(struct roc_sglist_comp);
446 : :
447 : 0 : size = g_size_bytes + s_size_bytes + ROC_SG_LIST_HDR_SIZE;
448 : :
449 : : /* This is DPTR len in case of SG mode */
450 : 0 : inst->w4.s.dlen = size;
451 : :
452 [ # # # # : 0 : if (unlikely(size > ROC_SG_MAX_DLEN_SIZE)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
453 : 0 : plt_dp_err("Exceeds max supported components. Reduce segments");
454 : : ret = -1;
455 : : }
456 : :
457 : 0 : inst->dptr = (uint64_t)in_buffer;
458 : 0 : return ret;
459 : : }
460 : :
461 : : static __rte_always_inline int
462 : : sg2_inst_prep(struct roc_se_fc_params *params, struct cpt_inst_s *inst, uint64_t offset_ctrl,
463 : : const uint8_t *iv_s, int iv_len, const bool pack_iv, uint8_t pdcp_alg_type,
464 : : int32_t inputlen, int32_t outputlen, uint32_t passthrough_len, uint32_t req_flags,
465 : : int pdcp_flag, int decrypt, uint32_t off_ctrl_len, const bool use_metadata)
466 : : {
467 : : struct roc_sg2list_comp *gather_comp, *scatter_comp;
468 : 0 : void *m_vaddr = params->meta_buf.vaddr;
469 : : struct roc_se_buf_ptr *aad_buf = NULL;
470 : : uint32_t mac_len = 0, aad_len = 0;
471 : : uint16_t scatter_sz, gather_sz;
472 : : union cpt_inst_w5 cpt_inst_w5;
473 : : union cpt_inst_w6 cpt_inst_w6;
474 : : struct roc_se_ctx *se_ctx;
475 : : uint32_t i, g_size_bytes;
476 : : uint64_t *offset_vaddr;
477 : : int zsk_flags, ret = 0;
478 : : uint32_t size;
479 : : uint8_t *iv_d;
480 : :
481 : : se_ctx = params->ctx;
482 : 0 : zsk_flags = se_ctx->zsk_flags;
483 : 0 : mac_len = se_ctx->mac_len;
484 : :
485 : 0 : if (unlikely(req_flags & ROC_SE_VALID_AAD_BUF)) {
486 : : /* We don't support both AAD and auth data separately */
487 : : aad_len = params->aad_buf.size;
488 : : aad_buf = ¶ms->aad_buf;
489 : : }
490 : :
491 : : /* save space for iv */
492 : : offset_vaddr = m_vaddr;
493 : :
494 : 0 : m_vaddr = (uint8_t *)m_vaddr + off_ctrl_len + RTE_ALIGN_CEIL(iv_len, 8);
495 : :
496 : 0 : inst->w4.s.opcode_major |= (uint64_t)ROC_DMA_MODE_SG;
497 : :
498 : : /* This is DPTR len in case of SG mode */
499 : 0 : inst->w4.s.dlen = inputlen + off_ctrl_len;
500 : :
501 : : /* iv offset is 0 */
502 : 0 : *offset_vaddr = offset_ctrl;
503 : :
504 [ # # # # : 0 : iv_d = ((uint8_t *)offset_vaddr + off_ctrl_len);
# # # # #
# # # ]
505 : : if (pdcp_flag) {
506 : 0 : if (likely(iv_len)) {
507 [ # # # # : 0 : if (zsk_flags == 0x1)
# # # # ]
508 : 0 : pdcp_iv_copy(iv_d + params->pdcp_iv_offset, iv_s, pdcp_alg_type,
509 : : pack_iv);
510 : : else
511 : 0 : pdcp_iv_copy(iv_d, iv_s, pdcp_alg_type, pack_iv);
512 : : }
513 : : } else {
514 [ # # # # : 0 : if (likely(iv_len))
# # # # #
# # # ]
515 : 0 : memcpy(iv_d, iv_s, iv_len);
516 : : }
517 : :
518 : : /* DPTR has SG list */
519 : :
520 : : /* TODO Add error check if space will be sufficient */
521 : : gather_comp = (struct roc_sg2list_comp *)((uint8_t *)m_vaddr);
522 : :
523 : : /*
524 : : * Input Gather List
525 : : */
526 : : i = 0;
527 : :
528 : : /* Offset control word followed by iv */
529 : :
530 [ # # # # : 0 : i = fill_sg2_comp(gather_comp, i, (uint64_t)offset_vaddr, off_ctrl_len + iv_len);
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
531 : :
532 : : /* Add input data */
533 [ # # # # : 0 : if (decrypt && (req_flags & ROC_SE_VALID_MAC_BUF)) {
# # # # #
# # # ]
534 : 0 : size = inputlen - iv_len - mac_len;
535 [ # # # # : 0 : if (size) {
# # # # #
# # # ]
536 : : /* input data only */
537 [ # # # # : 0 : if (unlikely(req_flags & ROC_SE_SINGLE_BUF_INPLACE)) {
# # # # ]
538 : : i = fill_sg2_comp_from_buf_min(gather_comp, i, params->bufs, &size);
539 : : } else {
540 [ # # # # : 0 : uint32_t aad_offset = aad_len ? passthrough_len : 0;
# # ]
541 : :
542 [ # # # # ]: 0 : i = fill_sg2_comp_from_iov(gather_comp, i, params->src_iov, 0,
543 : : &size, aad_buf, aad_offset);
544 : : }
545 [ # # # # : 0 : if (unlikely(size)) {
# # # # #
# # # ]
546 : 0 : plt_dp_err("Insufficient buffer"
547 : : " space, size %d needed",
548 : : size);
549 : 0 : return -1;
550 : : }
551 : : }
552 : :
553 : : /* mac data */
554 [ # # # # : 0 : if (mac_len)
# # # # #
# # # ]
555 : : i = fill_sg2_comp_from_buf(gather_comp, i, ¶ms->mac_buf);
556 : : } else {
557 : : /* input data */
558 : 0 : size = inputlen - iv_len;
559 [ # # # # : 0 : if (size) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
560 [ # # # # : 0 : uint32_t aad_offset = aad_len ? passthrough_len : 0;
# # # # #
# # # ]
561 [ # # # # : 0 : if (unlikely(req_flags & ROC_SE_SINGLE_BUF_INPLACE)) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
562 : : i = fill_sg2_comp_from_buf_min(gather_comp, i, params->bufs, &size);
563 : : } else {
564 [ # # # # : 0 : i = fill_sg2_comp_from_iov(gather_comp, i, params->src_iov, 0,
# # # # ]
565 : : &size, aad_buf, aad_offset);
566 : : }
567 [ # # # # : 0 : if (unlikely(size)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
568 : 0 : plt_dp_err("Insufficient buffer space,"
569 : : " size %d needed",
570 : : size);
571 : 0 : return -1;
572 : : }
573 : : }
574 : : }
575 : :
576 : 0 : gather_sz = (i + 2) / 3;
577 : 0 : g_size_bytes = gather_sz * sizeof(struct roc_sg2list_comp);
578 : :
579 : : /*
580 : : * Output Scatter List
581 : : */
582 : :
583 : : i = 0;
584 : 0 : scatter_comp = (struct roc_sg2list_comp *)((uint8_t *)gather_comp + g_size_bytes);
585 : :
586 [ # # # # : 0 : if ((zsk_flags == 0x1) && (se_ctx->fc_type == ROC_SE_KASUMI)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
587 : : /* IV in SLIST only for EEA3 & UEA2 or for F8 */
588 : : iv_len = 0;
589 : : }
590 : :
591 [ # # # # : 0 : if ((!use_metadata) && iv_len) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
592 : 0 : i = fill_sg2_comp(scatter_comp, i, (uint64_t)offset_vaddr + off_ctrl_len, iv_len);
593 : : }
594 : :
595 : : /* Add output data */
596 [ # # # # : 0 : if ((!decrypt) && (req_flags & ROC_SE_VALID_MAC_BUF)) {
# # # # #
# # # # #
# # ]
597 : 0 : size = outputlen - mac_len;
598 : : if (!use_metadata)
599 : 0 : size -= iv_len;
600 [ # # # # : 0 : if (size) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
601 : :
602 [ # # # # : 0 : uint32_t aad_offset = aad_len ? passthrough_len : 0;
# # ]
603 : :
604 [ # # # # : 0 : if (unlikely(req_flags & ROC_SE_SINGLE_BUF_INPLACE)) {
# # # # ]
605 : : i = fill_sg2_comp_from_buf_min(scatter_comp, i, params->bufs,
606 : : &size);
607 : : } else {
608 [ # # # # ]: 0 : i = fill_sg2_comp_from_iov(scatter_comp, i, params->dst_iov, 0,
609 : : &size, aad_buf, aad_offset);
610 : : }
611 [ # # # # : 0 : if (unlikely(size)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
612 : 0 : plt_dp_err("Insufficient buffer space,"
613 : : " size %d needed",
614 : : size);
615 : 0 : return -1;
616 : : }
617 : : }
618 : :
619 : : /* mac data */
620 [ # # # # : 0 : if (mac_len)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
621 : : i = fill_sg2_comp_from_buf(scatter_comp, i, ¶ms->mac_buf);
622 : : } else {
623 : : /* Output including mac */
624 : 0 : size = outputlen;
625 : : if (!use_metadata)
626 : 0 : size -= iv_len;
627 [ # # # # : 0 : if (size) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
628 [ # # # # : 0 : uint32_t aad_offset = aad_len ? passthrough_len : 0;
# # # # #
# # # ]
629 : :
630 [ # # # # : 0 : if (unlikely(req_flags & ROC_SE_SINGLE_BUF_INPLACE)) {
# # # # #
# # # # #
# # # # #
# # # #
# ]
631 : : i = fill_sg2_comp_from_buf_min(scatter_comp, i, params->bufs,
632 : : &size);
633 : : } else {
634 [ # # # # : 0 : i = fill_sg2_comp_from_iov(scatter_comp, i, params->dst_iov, 0,
# # # # ]
635 : : &size, aad_buf, aad_offset);
636 : : }
637 : :
638 [ # # # # : 0 : if (unlikely(size)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
639 : 0 : plt_dp_err("Insufficient buffer space,"
640 : : " size %d needed",
641 : : size);
642 : 0 : return -1;
643 : : }
644 : : }
645 : : }
646 : :
647 : 0 : scatter_sz = (i + 2) / 3;
648 : :
649 : 0 : cpt_inst_w5.s.gather_sz = gather_sz;
650 : 0 : cpt_inst_w6.s.scatter_sz = scatter_sz;
651 : :
652 : 0 : cpt_inst_w5.s.dptr = (uint64_t)gather_comp;
653 : 0 : cpt_inst_w6.s.rptr = (uint64_t)scatter_comp;
654 : :
655 : 0 : inst->w5.u64 = cpt_inst_w5.u64;
656 : 0 : inst->w6.u64 = cpt_inst_w6.u64;
657 : :
658 [ # # # # : 0 : if (unlikely((scatter_sz >> 4) || (gather_sz >> 4))) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
659 : 0 : plt_dp_err("Exceeds max supported components. Reduce segments");
660 : : ret = -1;
661 : : }
662 : :
663 : : return ret;
664 : : }
665 : :
666 : : static __rte_always_inline int
667 : : cpt_digest_gen_sg_ver1_prep(uint32_t flags, uint64_t d_lens, struct roc_se_fc_params *params,
668 : : struct cpt_inst_s *inst)
669 : : {
670 : : struct roc_sglist_comp *gather_comp, *scatter_comp;
671 : : void *m_vaddr = params->meta_buf.vaddr;
672 : : uint32_t g_size_bytes, s_size_bytes;
673 : : uint16_t data_len, mac_len, key_len;
674 : : union cpt_inst_w4 cpt_inst_w4;
675 : : roc_se_auth_type hash_type;
676 : : struct roc_se_ctx *ctx;
677 : : uint8_t *in_buffer;
678 : : uint32_t size, i;
679 : : int ret = 0;
680 : :
681 : : ctx = params->ctx;
682 : :
683 : 0 : hash_type = ctx->hash_type;
684 : 0 : mac_len = ctx->mac_len;
685 : 0 : key_len = ctx->auth_key_len;
686 : 0 : data_len = ROC_SE_AUTH_DLEN(d_lens);
687 : :
688 : 0 : cpt_inst_w4.u64 = ctx->template_w4.u64;
689 : 0 : cpt_inst_w4.s.param2 = ((uint16_t)hash_type << 8) | mac_len;
690 [ # # # # : 0 : if (ctx->hmac) {
# # ]
691 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_HMAC | ROC_DMA_MODE_SG;
692 : 0 : cpt_inst_w4.s.param1 = key_len;
693 : 0 : cpt_inst_w4.s.dlen = data_len + RTE_ALIGN_CEIL(key_len, 8);
694 : : } else {
695 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_HASH | ROC_DMA_MODE_SG;
696 : 0 : cpt_inst_w4.s.param1 = 0;
697 : 0 : cpt_inst_w4.s.dlen = data_len;
698 : : }
699 : :
700 : : /* DPTR has SG list */
701 : : in_buffer = m_vaddr;
702 : :
703 : 0 : ((uint16_t *)in_buffer)[0] = 0;
704 : 0 : ((uint16_t *)in_buffer)[1] = 0;
705 : :
706 : : /* TODO Add error check if space will be sufficient */
707 : 0 : gather_comp = (struct roc_sglist_comp *)((uint8_t *)m_vaddr + 8);
708 : :
709 : : /*
710 : : * Input gather list
711 : : */
712 : :
713 : : i = 0;
714 : :
715 [ # # # # : 0 : if (ctx->hmac) {
# # ]
716 : 0 : uint64_t k_vaddr = (uint64_t)ctx->auth_key;
717 : : /* Key */
718 : 0 : i = fill_sg_comp(gather_comp, i, k_vaddr,
719 [ # # # # : 0 : RTE_ALIGN_CEIL(key_len, 8));
# # ]
720 : : }
721 : :
722 : : /* input data */
723 : 0 : size = data_len;
724 : : i = fill_sg_comp_from_iov(gather_comp, i, params->src_iov, 0, &size, NULL, 0);
725 [ # # # # : 0 : if (unlikely(size)) {
# # ]
726 : 0 : plt_dp_err("Insufficient dst IOV size, short by %dB", size);
727 : : return -1;
728 : : }
729 [ # # # # : 0 : ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
# # ]
730 : 0 : g_size_bytes = ((i + 3) / 4) * sizeof(struct roc_sglist_comp);
731 : :
732 : : /*
733 : : * Output Gather list
734 : : */
735 : :
736 : : i = 0;
737 : 0 : scatter_comp = (struct roc_sglist_comp *)((uint8_t *)gather_comp + g_size_bytes);
738 : :
739 : : if (flags & ROC_SE_VALID_MAC_BUF) {
740 [ # # # # : 0 : if (unlikely(params->mac_buf.size < mac_len)) {
# # ]
741 : 0 : plt_dp_err("Insufficient MAC size");
742 : : return -1;
743 : : }
744 : :
745 : : size = mac_len;
746 : : i = fill_sg_comp_from_buf_min(scatter_comp, i, ¶ms->mac_buf,
747 : : &size);
748 : : } else {
749 : : size = mac_len;
750 : : i = fill_sg_comp_from_iov(scatter_comp, i, params->src_iov,
751 : : data_len, &size, NULL, 0);
752 : : if (unlikely(size)) {
753 : : plt_dp_err("Insufficient dst IOV size, short by %dB",
754 : : size);
755 : : return -1;
756 : : }
757 : : }
758 : :
759 : 0 : ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
760 : : s_size_bytes = ((i + 3) / 4) * sizeof(struct roc_sglist_comp);
761 : :
762 : 0 : size = g_size_bytes + s_size_bytes + ROC_SG_LIST_HDR_SIZE;
763 : :
764 [ # # # # : 0 : if (unlikely(size > ROC_SG_MAX_DLEN_SIZE)) {
# # ]
765 : 0 : plt_dp_err("Exceeds max supported components. Reduce segments");
766 : : ret = -1;
767 : : }
768 : :
769 : : /* This is DPTR len in case of SG mode */
770 : 0 : cpt_inst_w4.s.dlen = size;
771 : :
772 : 0 : inst->dptr = (uint64_t)in_buffer;
773 : 0 : inst->w4.u64 = cpt_inst_w4.u64;
774 : :
775 : : return ret;
776 : : }
777 : :
778 : : static __rte_always_inline int
779 : : cpt_digest_gen_sg_ver2_prep(uint32_t flags, uint64_t d_lens, struct roc_se_fc_params *params,
780 : : struct cpt_inst_s *inst)
781 : : {
782 : : uint16_t data_len, mac_len, key_len, scatter_sz, gather_sz;
783 : : struct roc_sg2list_comp *gather_comp, *scatter_comp;
784 : : void *m_vaddr = params->meta_buf.vaddr;
785 : : union cpt_inst_w4 cpt_inst_w4;
786 : : union cpt_inst_w5 cpt_inst_w5;
787 : : union cpt_inst_w6 cpt_inst_w6;
788 : : roc_se_auth_type hash_type;
789 : : struct roc_se_ctx *ctx;
790 : : uint32_t g_size_bytes;
791 : : uint32_t size, i;
792 : : int ret = 0;
793 : :
794 : : ctx = params->ctx;
795 : :
796 : 0 : hash_type = ctx->hash_type;
797 : 0 : mac_len = ctx->mac_len;
798 : 0 : key_len = ctx->auth_key_len;
799 : 0 : data_len = ROC_SE_AUTH_DLEN(d_lens);
800 : :
801 : 0 : cpt_inst_w4.u64 = ctx->template_w4.u64;
802 : 0 : cpt_inst_w4.s.param2 = ((uint16_t)hash_type << 8) | mac_len;
803 [ # # # # : 0 : if (ctx->hmac) {
# # ]
804 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_HMAC;
805 : 0 : cpt_inst_w4.s.param1 = key_len;
806 : 0 : cpt_inst_w4.s.dlen = data_len + RTE_ALIGN_CEIL(key_len, 8);
807 : : } else {
808 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_HASH;
809 : 0 : cpt_inst_w4.s.param1 = 0;
810 : 0 : cpt_inst_w4.s.dlen = data_len;
811 : : }
812 : :
813 : : /* DPTR has SG list */
814 : :
815 : : /* TODO Add error check if space will be sufficient */
816 : : gather_comp = (struct roc_sg2list_comp *)((uint8_t *)m_vaddr + 0);
817 : :
818 : : /*
819 : : * Input gather list
820 : : */
821 : :
822 : : i = 0;
823 : :
824 [ # # # # : 0 : if (ctx->hmac) {
# # ]
825 : 0 : uint64_t k_vaddr = (uint64_t)ctx->auth_key;
826 : : /* Key */
827 : 0 : i = fill_sg2_comp(gather_comp, i, k_vaddr, RTE_ALIGN_CEIL(key_len, 8));
828 : : }
829 : :
830 : : /* input data */
831 : 0 : size = data_len;
832 : : i = fill_sg2_comp_from_iov(gather_comp, i, params->src_iov, 0, &size, NULL, 0);
833 [ # # # # : 0 : if (unlikely(size)) {
# # ]
834 : 0 : plt_dp_err("Insufficient dst IOV size, short by %dB", size);
835 : : return -1;
836 : : }
837 : :
838 : 0 : gather_sz = (i + 2) / 3;
839 : 0 : g_size_bytes = gather_sz * sizeof(struct roc_sg2list_comp);
840 : :
841 : : /*
842 : : * Output Gather list
843 : : */
844 : :
845 : : i = 0;
846 : 0 : scatter_comp = (struct roc_sg2list_comp *)((uint8_t *)gather_comp + g_size_bytes);
847 : :
848 : : if (flags & ROC_SE_VALID_MAC_BUF) {
849 [ # # # # : 0 : if (unlikely(params->mac_buf.size < mac_len)) {
# # ]
850 : 0 : plt_dp_err("Insufficient MAC size");
851 : : return -1;
852 : : }
853 : :
854 : : size = mac_len;
855 : : i = fill_sg2_comp_from_buf_min(scatter_comp, i, ¶ms->mac_buf, &size);
856 : : } else {
857 : : size = mac_len;
858 : : i = fill_sg2_comp_from_iov(scatter_comp, i, params->src_iov, data_len, &size, NULL,
859 : : 0);
860 : : if (unlikely(size)) {
861 : : plt_dp_err("Insufficient dst IOV size, short by %dB", size);
862 : : return -1;
863 : : }
864 : : }
865 : :
866 : : scatter_sz = (i + 2) / 3;
867 : :
868 : 0 : cpt_inst_w5.s.gather_sz = gather_sz;
869 : 0 : cpt_inst_w6.s.scatter_sz = scatter_sz;
870 : :
871 : 0 : cpt_inst_w5.s.dptr = (uint64_t)gather_comp;
872 : 0 : cpt_inst_w6.s.rptr = (uint64_t)scatter_comp;
873 : :
874 : 0 : inst->w5.u64 = cpt_inst_w5.u64;
875 : 0 : inst->w6.u64 = cpt_inst_w6.u64;
876 : :
877 : 0 : inst->w4.u64 = cpt_inst_w4.u64;
878 : :
879 [ # # # # : 0 : if (unlikely((scatter_sz >> 4) || (gather_sz >> 4))) {
# # ]
880 : 0 : plt_dp_err("Exceeds max supported components. Reduce segments");
881 : : ret = -1;
882 : : }
883 : :
884 : : return ret;
885 : : }
886 : :
887 : : static inline int
888 : 0 : pdcp_chain_sg1_prep(struct roc_se_fc_params *params, struct roc_se_ctx *cpt_ctx,
889 : : struct cpt_inst_s *inst, union cpt_inst_w4 w4, int32_t inputlen,
890 : : uint8_t hdr_len, uint64_t offset_ctrl, uint32_t req_flags,
891 : : const uint8_t *cipher_iv, const uint8_t *auth_iv, const bool pack_iv,
892 : : const uint8_t pdcp_ci_alg, const uint8_t pdcp_auth_alg)
893 : : {
894 : : struct roc_sglist_comp *scatter_comp, *gather_comp;
895 : 0 : void *m_vaddr = params->meta_buf.vaddr;
896 : : uint32_t i, g_size_bytes, s_size_bytes;
897 : : const uint32_t mac_len = 4;
898 : : uint8_t *iv_d, *in_buffer;
899 : : uint64_t *offset_vaddr;
900 : : uint32_t size;
901 : : int ret = 0;
902 : :
903 : : /* save space for IV */
904 : : offset_vaddr = m_vaddr;
905 : :
906 : 0 : m_vaddr = PLT_PTR_ADD(m_vaddr, ROC_SE_OFF_CTRL_LEN + PLT_ALIGN_CEIL(hdr_len, 8));
907 : :
908 : 0 : w4.s.opcode_major |= (uint64_t)ROC_DMA_MODE_SG;
909 : :
910 : : /* DPTR has SG list */
911 : : in_buffer = m_vaddr;
912 : :
913 : 0 : ((uint16_t *)in_buffer)[0] = 0;
914 : 0 : ((uint16_t *)in_buffer)[1] = 0;
915 : :
916 : 0 : gather_comp = PLT_PTR_ADD(m_vaddr, 8);
917 : :
918 : : /* Input Gather List */
919 : : i = 0;
920 : :
921 : : /* Offset control word followed by IV */
922 : :
923 [ # # ]: 0 : i = fill_sg_comp(gather_comp, i, (uint64_t)offset_vaddr, ROC_SE_OFF_CTRL_LEN + hdr_len);
924 : :
925 : 0 : *(uint64_t *)offset_vaddr = offset_ctrl;
926 : :
927 : : /* Cipher IV */
928 : 0 : iv_d = ((uint8_t *)offset_vaddr + ROC_SE_OFF_CTRL_LEN);
929 : 0 : pdcp_iv_copy(iv_d, cipher_iv, pdcp_ci_alg, pack_iv);
930 : :
931 : : /* Auth IV */
932 : 0 : iv_d = ((uint8_t *)offset_vaddr + ROC_SE_OFF_CTRL_LEN + params->pdcp_iv_offset);
933 : 0 : pdcp_iv_copy(iv_d, auth_iv, pdcp_auth_alg, pack_iv);
934 : :
935 : : /* input data */
936 : 0 : size = inputlen - hdr_len;
937 [ # # ]: 0 : if (size) {
938 : 0 : i = fill_sg_comp_from_iov(gather_comp, i, params->src_iov, 0, &size, NULL, 0);
939 [ # # ]: 0 : if (unlikely(size)) {
940 : 0 : plt_dp_err("Insufficient buffer space, size %d needed", size);
941 : 0 : return -1;
942 : : }
943 : : }
944 [ # # ]: 0 : ((uint16_t *)in_buffer)[2] = rte_cpu_to_be_16(i);
945 : 0 : g_size_bytes = ((i + 3) / 4) * sizeof(struct roc_sglist_comp);
946 : :
947 : : /*
948 : : * Output Scatter List
949 : : */
950 : :
951 : : i = 0;
952 : 0 : scatter_comp = PLT_PTR_ADD(gather_comp, g_size_bytes);
953 : :
954 [ # # ]: 0 : if ((hdr_len)) {
955 [ # # ]: 0 : i = fill_sg_comp(scatter_comp, i, (uint64_t)offset_vaddr + ROC_SE_OFF_CTRL_LEN,
956 : : hdr_len);
957 : : }
958 : :
959 : : /* Add output data */
960 [ # # # # ]: 0 : if (cpt_ctx->ciph_then_auth && (req_flags & ROC_SE_VALID_MAC_BUF))
961 : 0 : size = inputlen;
962 : : else
963 : : /* Output including mac */
964 : 0 : size = inputlen + mac_len;
965 : :
966 : 0 : size -= hdr_len;
967 : :
968 [ # # ]: 0 : if (size) {
969 : 0 : i = fill_sg_comp_from_iov(scatter_comp, i, params->dst_iov, 0, &size, NULL, 0);
970 : :
971 [ # # ]: 0 : if (unlikely(size)) {
972 : 0 : plt_dp_err("Insufficient buffer space, size %d needed", size);
973 : 0 : return -1;
974 : : }
975 : : }
976 : :
977 [ # # ]: 0 : ((uint16_t *)in_buffer)[3] = rte_cpu_to_be_16(i);
978 : 0 : s_size_bytes = ((i + 3) / 4) * sizeof(struct roc_sglist_comp);
979 : :
980 : 0 : size = g_size_bytes + s_size_bytes + ROC_SG_LIST_HDR_SIZE;
981 : :
982 [ # # ]: 0 : if (unlikely(size > ROC_SG_MAX_DLEN_SIZE)) {
983 : 0 : plt_dp_err("Exceeds max supported components. Reduce segments");
984 : : ret = -1;
985 : : }
986 : :
987 : : /* This is DPTR len in case of SG mode */
988 : 0 : w4.s.dlen = size;
989 : 0 : inst->w4.u64 = w4.u64;
990 : :
991 : 0 : inst->dptr = (uint64_t)in_buffer;
992 : :
993 : 0 : return ret;
994 : : }
995 : :
996 : : static inline int
997 : 0 : pdcp_chain_sg2_prep(struct roc_se_fc_params *params, struct roc_se_ctx *cpt_ctx,
998 : : struct cpt_inst_s *inst, union cpt_inst_w4 w4, int32_t inputlen,
999 : : uint8_t hdr_len, uint64_t offset_ctrl, uint32_t req_flags,
1000 : : const uint8_t *cipher_iv, const uint8_t *auth_iv, const bool pack_iv,
1001 : : const uint8_t pdcp_ci_alg, const uint8_t pdcp_auth_alg, uint32_t pad_len,
1002 : : uint32_t off_ctrl_len, const bool use_metadata)
1003 : : {
1004 : : struct roc_sg2list_comp *gather_comp, *scatter_comp;
1005 : 0 : void *m_vaddr = params->meta_buf.vaddr;
1006 : : uint16_t scatter_sz, gather_sz;
1007 : : const uint32_t mac_len = 4;
1008 : : uint32_t i, g_size_bytes;
1009 : : uint64_t *offset_vaddr;
1010 : : union cpt_inst_w5 w5;
1011 : : union cpt_inst_w6 w6;
1012 : : uint8_t *iv_d;
1013 : : uint32_t size;
1014 : : int ret = 0;
1015 : :
1016 : : /* save space for IV */
1017 : : offset_vaddr = m_vaddr;
1018 : :
1019 : 0 : m_vaddr = PLT_PTR_ADD(m_vaddr, off_ctrl_len + RTE_ALIGN_CEIL(hdr_len, 8));
1020 : :
1021 : 0 : w4.s.opcode_major |= (uint64_t)ROC_DMA_MODE_SG;
1022 : 0 : w4.s.dlen = inputlen + off_ctrl_len;
1023 : :
1024 : : gather_comp = m_vaddr;
1025 : :
1026 : : /* Input Gather List */
1027 : : i = 0;
1028 : :
1029 : : /* Offset control word followed by IV */
1030 : 0 : *(uint64_t *)offset_vaddr = offset_ctrl;
1031 : :
1032 : 0 : i = fill_sg2_comp(gather_comp, i, (uint64_t)offset_vaddr, off_ctrl_len + hdr_len);
1033 : :
1034 : : /* Cipher IV */
1035 : 0 : iv_d = ((uint8_t *)offset_vaddr + off_ctrl_len);
1036 : 0 : pdcp_iv_copy(iv_d, cipher_iv, pdcp_ci_alg, pack_iv);
1037 : :
1038 : : /* Auth IV */
1039 : 0 : iv_d = ((uint8_t *)offset_vaddr + off_ctrl_len + params->pdcp_iv_offset);
1040 : 0 : pdcp_iv_copy(iv_d, auth_iv, pdcp_auth_alg, pack_iv);
1041 : :
1042 : : /* input data */
1043 : 0 : size = inputlen - hdr_len;
1044 [ # # ]: 0 : if (size) {
1045 : 0 : i = fill_sg2_comp_from_iov(gather_comp, i, params->src_iov, 0, &size, NULL, 0);
1046 [ # # ]: 0 : if (unlikely(size)) {
1047 : 0 : plt_dp_err("Insufficient buffer space, size %d needed", size);
1048 : 0 : return -1;
1049 : : }
1050 : : }
1051 : :
1052 : 0 : gather_sz = (i + 2) / 3;
1053 : 0 : g_size_bytes = gather_sz * sizeof(struct roc_sg2list_comp);
1054 : :
1055 : : /*
1056 : : * Output Scatter List
1057 : : */
1058 : :
1059 : : i = 0;
1060 : 0 : scatter_comp = PLT_PTR_ADD(gather_comp, g_size_bytes);
1061 : :
1062 [ # # ]: 0 : if (use_metadata && pad_len)
1063 : : /* Add padding */
1064 : 0 : i = fill_sg2_comp(scatter_comp, i, (uint64_t)(offset_vaddr) + off_ctrl_len,
1065 : : pad_len);
1066 : :
1067 [ # # ]: 0 : if ((!use_metadata) && hdr_len)
1068 : 0 : i = fill_sg2_comp(scatter_comp, i, (uint64_t)(offset_vaddr) + off_ctrl_len,
1069 : : hdr_len);
1070 : :
1071 : : /* Add output data */
1072 [ # # # # ]: 0 : if (cpt_ctx->ciph_then_auth && (req_flags & ROC_SE_VALID_MAC_BUF))
1073 : 0 : size = inputlen;
1074 : : else
1075 : : /* Output including mac */
1076 : 0 : size = inputlen + mac_len;
1077 : :
1078 : 0 : size -= hdr_len;
1079 : :
1080 [ # # ]: 0 : if (size) {
1081 : 0 : i = fill_sg2_comp_from_iov(scatter_comp, i, params->dst_iov, 0, &size, NULL, 0);
1082 : :
1083 [ # # ]: 0 : if (unlikely(size)) {
1084 : 0 : plt_dp_err("Insufficient buffer space, size %d needed", size);
1085 : 0 : return -1;
1086 : : }
1087 : : }
1088 : :
1089 : 0 : scatter_sz = (i + 2) / 3;
1090 : :
1091 : 0 : w5.s.gather_sz = gather_sz;
1092 : 0 : w6.s.scatter_sz = scatter_sz;
1093 : :
1094 : 0 : w5.s.dptr = (uint64_t)gather_comp;
1095 : 0 : w6.s.rptr = (uint64_t)scatter_comp;
1096 : :
1097 : 0 : inst->w4.u64 = w4.u64;
1098 : 0 : inst->w5.u64 = w5.u64;
1099 : 0 : inst->w6.u64 = w6.u64;
1100 : :
1101 [ # # # # ]: 0 : if (unlikely((scatter_sz >> 4) || (gather_sz >> 4))) {
1102 : 0 : plt_dp_err("Exceeds max supported components. Reduce segments");
1103 : : ret = -1;
1104 : : }
1105 : :
1106 : : return ret;
1107 : : }
1108 : :
1109 : : static __rte_always_inline int
1110 : : cpt_sm_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens, struct roc_se_fc_params *fc_params,
1111 : : struct cpt_inst_s *inst, const bool is_sg_ver2, int decrypt)
1112 : : {
1113 : : int32_t inputlen, outputlen, enc_dlen;
1114 : : union cpt_inst_w4 cpt_inst_w4;
1115 : : uint32_t passthr_len, pad_len;
1116 : : uint32_t passthrough_len = 0;
1117 : : const uint8_t *src = NULL;
1118 : : struct roc_se_ctx *se_ctx;
1119 : : uint32_t encr_data_len;
1120 : : uint32_t encr_offset;
1121 : : uint64_t offset_ctrl;
1122 : : uint8_t iv_len = 16;
1123 : : void *offset_vaddr;
1124 : : int ret;
1125 : :
1126 : 0 : encr_offset = ROC_SE_ENCR_OFFSET(d_offs);
1127 : : encr_data_len = ROC_SE_ENCR_DLEN(d_lens);
1128 : :
1129 : : se_ctx = fc_params->ctx;
1130 : 0 : cpt_inst_w4.u64 = se_ctx->template_w4.u64;
1131 : :
1132 [ # # # # ]: 0 : if (unlikely(!(flags & ROC_SE_VALID_IV_BUF)))
1133 : : iv_len = 0;
1134 : :
1135 : 0 : passthr_len = encr_offset + iv_len;
1136 : 0 : passthr_len = RTE_ALIGN_CEIL(passthr_len, 8);
1137 : 0 : pad_len = passthr_len - encr_offset - iv_len;
1138 : 0 : enc_dlen = RTE_ALIGN_CEIL(encr_data_len, 8) + passthr_len;
1139 : :
1140 : : inputlen = enc_dlen;
1141 : : outputlen = enc_dlen;
1142 : :
1143 : 0 : cpt_inst_w4.s.param1 = encr_data_len;
1144 : :
1145 : 0 : offset_ctrl = passthr_len & 0xff;
1146 [ # # # # ]: 0 : offset_ctrl = rte_cpu_to_be_64(offset_ctrl);
1147 : :
1148 : : /*
1149 : : * In cn9k, cn10k since we have a limitation of
1150 : : * IV & Offset control word not part of instruction
1151 : : * and need to be part of Data Buffer, we check if
1152 : : * head room is there and then only do the Direct mode processing
1153 : : */
1154 [ # # # # ]: 0 : if (likely((flags & ROC_SE_SINGLE_BUF_INPLACE) && (flags & ROC_SE_SINGLE_BUF_HEADROOM))) {
1155 : : void *dm_vaddr = fc_params->bufs[0].vaddr;
1156 : :
1157 : : /* Use Direct mode */
1158 : :
1159 : 0 : offset_vaddr = PLT_PTR_SUB(dm_vaddr, ROC_SE_OFF_CTRL_LEN + pad_len + iv_len);
1160 : 0 : *(uint64_t *)offset_vaddr = offset_ctrl;
1161 : :
1162 : : /* DPTR */
1163 : 0 : inst->dptr = (uint64_t)offset_vaddr;
1164 : :
1165 : : /* RPTR should just exclude offset control word */
1166 : 0 : inst->rptr = (uint64_t)dm_vaddr - iv_len - pad_len;
1167 : :
1168 : 0 : cpt_inst_w4.s.dlen = inputlen + ROC_SE_OFF_CTRL_LEN;
1169 : :
1170 [ # # # # ]: 0 : if (likely(iv_len)) {
1171 [ # # # # ]: 0 : void *dst = PLT_PTR_ADD(offset_vaddr, ROC_SE_OFF_CTRL_LEN);
1172 : : const uint64_t *src = fc_params->iv_buf;
1173 : :
1174 : : rte_memcpy(dst, src, 16);
1175 : : }
1176 : 0 : inst->w4.u64 = cpt_inst_w4.u64;
1177 : : } else {
1178 [ # # # # ]: 0 : if (likely(iv_len))
1179 : : src = fc_params->iv_buf;
1180 : :
1181 : 0 : inst->w4.u64 = cpt_inst_w4.u64;
1182 : :
1183 [ # # # # ]: 0 : if (is_sg_ver2)
1184 [ # # # # ]: 0 : ret = sg2_inst_prep(fc_params, inst, offset_ctrl, src, iv_len + pad_len, 0,
1185 : : 0, inputlen, outputlen, passthrough_len, flags, 0,
1186 : : decrypt, ROC_SE_OFF_CTRL_LEN, false);
1187 : : else
1188 [ # # # # ]: 0 : ret = sg_inst_prep(fc_params, inst, offset_ctrl, src, iv_len + pad_len, 0,
1189 : : 0, inputlen, outputlen, passthrough_len, flags, 0,
1190 : : decrypt);
1191 : :
1192 [ # # # # ]: 0 : if (unlikely(ret)) {
1193 : 0 : plt_dp_err("sg prep failed");
1194 : 0 : return -1;
1195 : : }
1196 : : }
1197 : :
1198 : : return 0;
1199 : : }
1200 : :
1201 : : static __rte_always_inline int
1202 : : cpt_enc_hmac_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens,
1203 : : struct roc_se_fc_params *fc_params, struct cpt_inst_s *inst,
1204 : : const bool is_sg_ver2)
1205 : : {
1206 : : uint32_t encr_data_len, auth_data_len, aad_len = 0;
1207 : : uint32_t encr_offset, auth_offset, iv_offset = 0;
1208 : : int32_t inputlen, outputlen, enc_dlen, auth_dlen;
1209 : : uint32_t cipher_type, hash_type;
1210 : : union cpt_inst_w4 cpt_inst_w4;
1211 : : uint32_t passthrough_len = 0;
1212 : : const uint8_t *src = NULL;
1213 : : struct roc_se_ctx *se_ctx;
1214 : : uint64_t offset_ctrl;
1215 : : uint8_t iv_len = 16;
1216 : : void *offset_vaddr;
1217 : : uint8_t op_minor;
1218 : : uint32_t mac_len;
1219 : : int ret;
1220 : :
1221 : 0 : encr_offset = ROC_SE_ENCR_OFFSET(d_offs);
1222 : 0 : auth_offset = ROC_SE_AUTH_OFFSET(d_offs);
1223 : 0 : encr_data_len = ROC_SE_ENCR_DLEN(d_lens);
1224 : 0 : auth_data_len = ROC_SE_AUTH_DLEN(d_lens);
1225 [ # # # # : 0 : if (unlikely(flags & ROC_SE_VALID_AAD_BUF)) {
# # ]
1226 : : /* We don't support both AAD and auth data separately */
1227 : : auth_data_len = 0;
1228 : : auth_offset = 0;
1229 : 0 : aad_len = fc_params->aad_buf.size;
1230 : : }
1231 : :
1232 : : se_ctx = fc_params->ctx;
1233 : 0 : cipher_type = se_ctx->enc_cipher;
1234 : 0 : hash_type = se_ctx->hash_type;
1235 : 0 : mac_len = se_ctx->mac_len;
1236 : 0 : cpt_inst_w4.u64 = se_ctx->template_w4.u64;
1237 : : op_minor = cpt_inst_w4.s.opcode_minor;
1238 : :
1239 [ # # # # : 0 : if (unlikely(!(flags & ROC_SE_VALID_IV_BUF))) {
# # # # #
# # # ]
1240 : : iv_len = 0;
1241 : 0 : iv_offset = ROC_SE_ENCR_IV_OFFSET(d_offs);
1242 : : }
1243 : :
1244 [ # # # # : 0 : if (unlikely(flags & ROC_SE_VALID_AAD_BUF)) {
# # ]
1245 : : /*
1246 : : * When AAD is given, data above encr_offset is pass through
1247 : : * Since AAD is given as separate pointer and not as offset,
1248 : : * this is a special case as we need to fragment input data
1249 : : * into passthrough + encr_data and then insert AAD in between.
1250 : : */
1251 [ # # # # : 0 : if (hash_type != ROC_SE_GMAC_TYPE) {
# # ]
1252 : : passthrough_len = encr_offset;
1253 : 0 : auth_offset = passthrough_len + iv_len;
1254 : 0 : encr_offset = passthrough_len + aad_len + iv_len;
1255 : 0 : auth_data_len = aad_len + encr_data_len;
1256 : : } else {
1257 : 0 : passthrough_len = 16 + aad_len;
1258 : 0 : auth_offset = passthrough_len + iv_len;
1259 : : auth_data_len = aad_len;
1260 : : }
1261 : : } else {
1262 : 0 : encr_offset += iv_len;
1263 : 0 : auth_offset += iv_len;
1264 : : }
1265 : :
1266 : : /* Encryption */
1267 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_FC;
1268 : : cpt_inst_w4.s.opcode_minor |= ROC_SE_FC_MINOR_OP_ENCRYPT;
1269 : :
1270 [ # # # # : 0 : if (hash_type == ROC_SE_GMAC_TYPE) {
# # # # #
# # # # #
# # ]
1271 : : encr_offset = 0;
1272 : : encr_data_len = 0;
1273 : : }
1274 : :
1275 : 0 : auth_dlen = auth_offset + auth_data_len;
1276 : 0 : enc_dlen = encr_data_len + encr_offset;
1277 [ # # # # : 0 : if (unlikely(encr_data_len & 0xf)) {
# # # # #
# # # ]
1278 [ # # # # : 0 : if ((cipher_type == ROC_SE_DES3_CBC) ||
# # # # #
# # # ]
1279 : : (cipher_type == ROC_SE_DES3_ECB))
1280 : 0 : enc_dlen =
1281 : 0 : RTE_ALIGN_CEIL(encr_data_len, 8) + encr_offset;
1282 [ # # # # : 0 : else if (likely((cipher_type == ROC_SE_AES_CBC) ||
# # # # #
# # # ]
1283 : : (cipher_type == ROC_SE_AES_ECB)))
1284 : 0 : enc_dlen =
1285 : 0 : RTE_ALIGN_CEIL(encr_data_len, 8) + encr_offset;
1286 : : }
1287 : :
1288 [ # # # # : 0 : if (unlikely(auth_dlen > enc_dlen)) {
# # # # #
# # # # #
# # # # ]
1289 : : inputlen = auth_dlen;
1290 : 0 : outputlen = auth_dlen + mac_len;
1291 : : } else {
1292 : : inputlen = enc_dlen;
1293 : 0 : outputlen = enc_dlen + mac_len;
1294 : : }
1295 : :
1296 [ # # # # : 0 : if (op_minor & ROC_SE_FC_MINOR_OP_HMAC_FIRST)
# # # # #
# # # # #
# # # # ]
1297 : : outputlen = enc_dlen;
1298 : :
1299 : 0 : cpt_inst_w4.s.param1 = encr_data_len;
1300 : 0 : cpt_inst_w4.s.param2 = auth_data_len;
1301 : :
1302 [ # # # # : 0 : if (unlikely((encr_offset >> 16) || (iv_offset >> 8) || (auth_offset >> 8))) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
1303 : 0 : plt_dp_err("Offset not supported");
1304 : 0 : plt_dp_err("enc_offset: %d", encr_offset);
1305 : 0 : plt_dp_err("iv_offset : %d", iv_offset);
1306 : 0 : plt_dp_err("auth_offset: %d", auth_offset);
1307 : 0 : return -1;
1308 : : }
1309 : :
1310 [ # # # # : 0 : offset_ctrl = rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | ((uint64_t)iv_offset << 8) |
# # # # #
# # # # #
# # # # ]
1311 : : ((uint64_t)auth_offset));
1312 : :
1313 : : /*
1314 : : * In cn9k, cn10k since we have a limitation of
1315 : : * IV & Offset control word not part of instruction
1316 : : * and need to be part of Data Buffer, we check if
1317 : : * head room is there and then only do the Direct mode processing
1318 : : */
1319 [ # # # # : 0 : if (likely((flags & ROC_SE_SINGLE_BUF_INPLACE) &&
# # # # ]
1320 : : (flags & ROC_SE_SINGLE_BUF_HEADROOM))) {
1321 : 0 : void *dm_vaddr = fc_params->bufs[0].vaddr;
1322 : :
1323 : : /* Use Direct mode */
1324 : :
1325 : 0 : offset_vaddr = (uint8_t *)dm_vaddr - ROC_SE_OFF_CTRL_LEN - iv_len;
1326 : :
1327 : 0 : *(uint64_t *)offset_vaddr =
1328 [ # # # # : 0 : rte_cpu_to_be_64(((uint64_t)encr_offset << 16) |
# # # # ]
1329 : : ((uint64_t)iv_offset << 8) | ((uint64_t)auth_offset));
1330 : :
1331 : : /* DPTR */
1332 : 0 : inst->dptr = (uint64_t)offset_vaddr;
1333 : :
1334 : : /* RPTR should just exclude offset control word */
1335 : 0 : inst->rptr = (uint64_t)dm_vaddr - iv_len;
1336 : :
1337 : 0 : cpt_inst_w4.s.dlen = inputlen + ROC_SE_OFF_CTRL_LEN;
1338 : :
1339 [ # # # # : 0 : if (likely(iv_len)) {
# # # # ]
1340 : : uint64_t *dest =
1341 : : (uint64_t *)((uint8_t *)offset_vaddr + ROC_SE_OFF_CTRL_LEN);
1342 : 0 : const uint64_t *src = fc_params->iv_buf;
1343 : 0 : dest[0] = src[0];
1344 : 0 : dest[1] = src[1];
1345 : : }
1346 : :
1347 : 0 : inst->w4.u64 = cpt_inst_w4.u64;
1348 : : } else {
1349 [ # # # # : 0 : if (likely(iv_len))
# # # # #
# # # ]
1350 : 0 : src = fc_params->iv_buf;
1351 : :
1352 [ # # # # : 0 : inst->w4.u64 = cpt_inst_w4.u64;
# # ]
1353 : :
1354 [ # # # # : 0 : if (is_sg_ver2)
# # # # #
# # # # #
# # # # ]
1355 [ # # # # : 0 : ret = sg2_inst_prep(fc_params, inst, offset_ctrl, src, iv_len, 0, 0,
# # # # #
# # # ]
1356 : : inputlen, outputlen, passthrough_len, flags, 0, 0,
1357 : : ROC_SE_OFF_CTRL_LEN, false);
1358 : : else
1359 [ # # # # : 0 : ret = sg_inst_prep(fc_params, inst, offset_ctrl, src, iv_len, 0, 0,
# # # # #
# # # ]
1360 : : inputlen, outputlen, passthrough_len, flags, 0, 0);
1361 : :
1362 [ # # # # : 0 : if (unlikely(ret)) {
# # # # #
# # # # #
# # # # ]
1363 : 0 : plt_dp_err("sg prep failed");
1364 : 0 : return -1;
1365 : : }
1366 : : }
1367 : :
1368 : : return 0;
1369 : : }
1370 : :
1371 : : static __rte_always_inline int
1372 : : cpt_dec_hmac_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens,
1373 : : struct roc_se_fc_params *fc_params, struct cpt_inst_s *inst,
1374 : : const bool is_sg_ver2)
1375 : : {
1376 : : uint32_t encr_data_len, auth_data_len, aad_len = 0;
1377 : : uint32_t encr_offset, auth_offset, iv_offset = 0;
1378 : : int32_t inputlen, outputlen, enc_dlen, auth_dlen;
1379 : : union cpt_inst_w4 cpt_inst_w4;
1380 : : uint32_t passthrough_len = 0;
1381 : : int32_t hash_type, mac_len;
1382 : : const uint8_t *src = NULL;
1383 : : struct roc_se_ctx *se_ctx;
1384 : : uint64_t offset_ctrl;
1385 : : uint8_t iv_len = 16;
1386 : : void *offset_vaddr;
1387 : : uint8_t op_minor;
1388 : : int ret;
1389 : :
1390 : 0 : encr_offset = ROC_SE_ENCR_OFFSET(d_offs);
1391 : 0 : auth_offset = ROC_SE_AUTH_OFFSET(d_offs);
1392 : 0 : encr_data_len = ROC_SE_ENCR_DLEN(d_lens);
1393 : 0 : auth_data_len = ROC_SE_AUTH_DLEN(d_lens);
1394 : :
1395 [ # # # # : 0 : if (unlikely(flags & ROC_SE_VALID_AAD_BUF)) {
# # ]
1396 : : /* We don't support both AAD and auth data separately */
1397 : : auth_data_len = 0;
1398 : : auth_offset = 0;
1399 : 0 : aad_len = fc_params->aad_buf.size;
1400 : : }
1401 : :
1402 : : se_ctx = fc_params->ctx;
1403 : 0 : hash_type = se_ctx->hash_type;
1404 : 0 : mac_len = se_ctx->mac_len;
1405 : 0 : cpt_inst_w4.u64 = se_ctx->template_w4.u64;
1406 : : op_minor = cpt_inst_w4.s.opcode_minor;
1407 : :
1408 [ # # # # : 0 : if (unlikely(!(flags & ROC_SE_VALID_IV_BUF))) {
# # # # #
# # # ]
1409 : : iv_len = 0;
1410 : 0 : iv_offset = ROC_SE_ENCR_IV_OFFSET(d_offs);
1411 : : }
1412 : :
1413 [ # # # # : 0 : if (unlikely(flags & ROC_SE_VALID_AAD_BUF)) {
# # ]
1414 : : /*
1415 : : * When AAD is given, data above encr_offset is pass through
1416 : : * Since AAD is given as separate pointer and not as offset,
1417 : : * this is a special case as we need to fragment input data
1418 : : * into passthrough + encr_data and then insert AAD in between.
1419 : : */
1420 [ # # # # : 0 : if (hash_type != ROC_SE_GMAC_TYPE) {
# # ]
1421 : : passthrough_len = encr_offset;
1422 : 0 : auth_offset = passthrough_len + iv_len;
1423 : 0 : encr_offset = passthrough_len + aad_len + iv_len;
1424 : 0 : auth_data_len = aad_len + encr_data_len;
1425 : : } else {
1426 : 0 : passthrough_len = 16 + aad_len;
1427 : 0 : auth_offset = passthrough_len + iv_len;
1428 : : auth_data_len = aad_len;
1429 : : }
1430 : : } else {
1431 : 0 : encr_offset += iv_len;
1432 : 0 : auth_offset += iv_len;
1433 : : }
1434 : :
1435 : : /* Decryption */
1436 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_FC;
1437 : : cpt_inst_w4.s.opcode_minor = ROC_SE_FC_MINOR_OP_DECRYPT;
1438 : 0 : cpt_inst_w4.s.opcode_minor |= (uint64_t)op_minor;
1439 : :
1440 [ # # # # : 0 : if (hash_type == ROC_SE_GMAC_TYPE) {
# # # # #
# # # ]
1441 : : encr_offset = 0;
1442 : : encr_data_len = 0;
1443 : : }
1444 : :
1445 : 0 : enc_dlen = encr_offset + encr_data_len;
1446 : 0 : auth_dlen = auth_offset + auth_data_len;
1447 : :
1448 [ # # # # : 0 : if (auth_dlen > enc_dlen) {
# # # # #
# # # ]
1449 : 0 : inputlen = auth_dlen + mac_len;
1450 : : outputlen = auth_dlen;
1451 : : } else {
1452 : 0 : inputlen = enc_dlen + mac_len;
1453 : : outputlen = enc_dlen;
1454 : : }
1455 : :
1456 [ # # # # : 0 : if (op_minor & ROC_SE_FC_MINOR_OP_HMAC_FIRST)
# # # # #
# # # ]
1457 : : outputlen = inputlen = enc_dlen;
1458 : :
1459 : 0 : cpt_inst_w4.s.param1 = encr_data_len;
1460 : 0 : cpt_inst_w4.s.param2 = auth_data_len;
1461 : :
1462 [ # # # # : 0 : if (unlikely((encr_offset >> 16) || (iv_offset >> 8) || (auth_offset >> 8))) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # ]
1463 : 0 : plt_dp_err("Offset not supported");
1464 : 0 : plt_dp_err("enc_offset: %d", encr_offset);
1465 : 0 : plt_dp_err("iv_offset : %d", iv_offset);
1466 : 0 : plt_dp_err("auth_offset: %d", auth_offset);
1467 : 0 : return -1;
1468 : : }
1469 : :
1470 [ # # # # : 0 : offset_ctrl = rte_cpu_to_be_64(((uint64_t)encr_offset << 16) | ((uint64_t)iv_offset << 8) |
# # # # #
# # # ]
1471 : : ((uint64_t)auth_offset));
1472 : :
1473 : : /*
1474 : : * In cn9k, cn10k since we have a limitation of
1475 : : * IV & Offset control word not part of instruction
1476 : : * and need to be part of Data Buffer, we check if
1477 : : * head room is there and then only do the Direct mode processing
1478 : : */
1479 [ # # # # : 0 : if (likely((flags & ROC_SE_SINGLE_BUF_INPLACE) && (flags & ROC_SE_SINGLE_BUF_HEADROOM))) {
# # # # ]
1480 : 0 : void *dm_vaddr = fc_params->bufs[0].vaddr;
1481 : :
1482 : : /* Use Direct mode */
1483 : :
1484 : 0 : offset_vaddr = (uint8_t *)dm_vaddr - ROC_SE_OFF_CTRL_LEN - iv_len;
1485 : :
1486 : 0 : *(uint64_t *)offset_vaddr =
1487 [ # # # # : 0 : rte_cpu_to_be_64(((uint64_t)encr_offset << 16) |
# # # # ]
1488 : : ((uint64_t)iv_offset << 8) | ((uint64_t)auth_offset));
1489 : :
1490 : 0 : inst->dptr = (uint64_t)offset_vaddr;
1491 : :
1492 : : /* RPTR should just exclude offset control word */
1493 : 0 : inst->rptr = (uint64_t)dm_vaddr - iv_len;
1494 : :
1495 : 0 : cpt_inst_w4.s.dlen = inputlen + ROC_SE_OFF_CTRL_LEN;
1496 : :
1497 [ # # # # : 0 : if (likely(iv_len)) {
# # # # ]
1498 : : uint64_t *dest =
1499 : : (uint64_t *)((uint8_t *)offset_vaddr + ROC_SE_OFF_CTRL_LEN);
1500 : 0 : const uint64_t *src = fc_params->iv_buf;
1501 : 0 : dest[0] = src[0];
1502 : 0 : dest[1] = src[1];
1503 : : }
1504 : 0 : inst->w4.u64 = cpt_inst_w4.u64;
1505 : :
1506 : : } else {
1507 [ # # # # : 0 : if (likely(iv_len)) {
# # # # #
# # # ]
1508 : 0 : src = fc_params->iv_buf;
1509 : : }
1510 : :
1511 : 0 : inst->w4.u64 = cpt_inst_w4.u64;
1512 : :
1513 [ # # # # : 0 : if (is_sg_ver2)
# # # # #
# # # ]
1514 [ # # # # : 0 : ret = sg2_inst_prep(fc_params, inst, offset_ctrl, src, iv_len, 0, 0,
# # # # #
# # # ]
1515 : : inputlen, outputlen, passthrough_len, flags, 0, 1,
1516 : : ROC_SE_OFF_CTRL_LEN, false);
1517 : : else
1518 [ # # # # : 0 : ret = sg_inst_prep(fc_params, inst, offset_ctrl, src, iv_len, 0, 0,
# # # # #
# # # ]
1519 : : inputlen, outputlen, passthrough_len, flags, 0, 1);
1520 [ # # # # : 0 : if (unlikely(ret)) {
# # # # #
# # # ]
1521 : 0 : plt_dp_err("sg prep failed");
1522 : 0 : return -1;
1523 : : }
1524 : : }
1525 : :
1526 : : return 0;
1527 : : }
1528 : :
1529 : : static __rte_always_inline int
1530 : : cpt_pdcp_chain_alg_prep(uint32_t req_flags, uint64_t d_offs, uint64_t d_lens,
1531 : : struct roc_se_fc_params *params, struct cpt_inst_s *inst,
1532 : : struct cpt_inflight_req *infl_req, const bool is_sg_ver2,
1533 : : const bool use_metadata)
1534 : : {
1535 : : uint32_t encr_data_len, auth_data_len, aad_len, passthr_len, pad_len, hdr_len;
1536 : : uint32_t encr_offset, auth_offset, iv_offset = 0;
1537 : : const uint8_t *auth_iv = NULL, *cipher_iv = NULL;
1538 : 0 : uint8_t pdcp_iv_off = params->pdcp_iv_offset;
1539 : : uint32_t off_ctrl_len = ROC_SE_OFF_CTRL_LEN;
1540 : 0 : const int iv_len = pdcp_iv_off * 2;
1541 : : uint8_t pdcp_ci_alg, pdcp_auth_alg;
1542 : : union cpt_inst_w4 cpt_inst_w4;
1543 : : struct roc_se_ctx *se_ctx;
1544 : : uint64_t *offset_vaddr;
1545 : : uint64_t offset_ctrl;
1546 : : int32_t inputlen;
1547 : : void *dm_vaddr;
1548 : : uint8_t *iv_d;
1549 : :
1550 : 0 : encr_offset = ROC_SE_ENCR_OFFSET(d_offs);
1551 : 0 : auth_offset = ROC_SE_AUTH_OFFSET(d_offs);
1552 : :
1553 : 0 : aad_len = encr_offset - auth_offset;
1554 : :
1555 : : if (unlikely(encr_offset >> 16)) {
1556 : : plt_dp_err("Offset not supported");
1557 : : plt_dp_err("enc_offset: %d", encr_offset);
1558 : : return -1;
1559 : : }
1560 : :
1561 : 0 : se_ctx = params->ctx;
1562 : 0 : pdcp_ci_alg = se_ctx->pdcp_ci_alg;
1563 : 0 : pdcp_auth_alg = se_ctx->pdcp_auth_alg;
1564 : :
1565 : 0 : encr_data_len = ROC_SE_ENCR_DLEN(d_lens);
1566 : 0 : auth_data_len = ROC_SE_AUTH_DLEN(d_lens);
1567 : 0 : auth_data_len -= aad_len;
1568 : :
1569 : : if (!use_metadata) {
1570 : 0 : encr_offset += iv_len;
1571 : 0 : auth_offset = encr_offset - aad_len;
1572 : : }
1573 : 0 : passthr_len = RTE_ALIGN_CEIL(auth_offset, 8);
1574 : :
1575 [ # # # # ]: 0 : if (unlikely((aad_len >> 16) || (passthr_len >> 8))) {
1576 : 0 : plt_dp_err("Length not supported");
1577 : 0 : plt_dp_err("AAD_len: %d", aad_len);
1578 : 0 : plt_dp_err("Passthrough_len: %d", passthr_len);
1579 : 0 : return -1;
1580 : : }
1581 : :
1582 : 0 : cpt_inst_w4.u64 = se_ctx->template_w4.u64;
1583 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
1584 : :
1585 : 0 : cpt_inst_w4.s.param1 = auth_data_len;
1586 : 0 : cpt_inst_w4.s.param2 = 0;
1587 : :
1588 [ # # # # ]: 0 : if (likely(params->auth_iv_len))
1589 : 0 : auth_iv = params->auth_iv_buf;
1590 : :
1591 [ # # # # ]: 0 : if (likely(params->cipher_iv_len))
1592 : 0 : cipher_iv = params->iv_buf;
1593 : :
1594 : 0 : pad_len = passthr_len - auth_offset;
1595 : 0 : hdr_len = iv_len + pad_len;
1596 : :
1597 [ # # # # ]: 0 : if (se_ctx->auth_then_ciph)
1598 : 0 : inputlen = auth_data_len;
1599 : : else
1600 : 0 : inputlen = encr_data_len;
1601 : :
1602 : 0 : inputlen += (encr_offset + pad_len);
1603 : : if (use_metadata)
1604 : 0 : inputlen += iv_len;
1605 : :
1606 [ # # # # ]: 0 : offset_ctrl = rte_cpu_to_be_64(((uint64_t)(aad_len) << 16) | ((uint64_t)(iv_offset) << 8) |
1607 : : ((uint64_t)(passthr_len)));
1608 : :
1609 : : if (use_metadata)
1610 : : off_ctrl_len *= 2;
1611 : :
1612 [ # # # # ]: 0 : if (likely(((req_flags & ROC_SE_SINGLE_BUF_INPLACE)) &&
1613 : : ((req_flags & ROC_SE_SINGLE_BUF_HEADROOM)))) {
1614 : :
1615 : 0 : dm_vaddr = params->bufs[0].vaddr;
1616 : :
1617 : : /* Use Direct mode */
1618 : : if (use_metadata) {
1619 : 0 : inst->w0.cn20k.pkt_ctl = META_PKT_CTL_ENABLE;
1620 : 0 : inst->meta_sz = META_LEN / META_SIZE_DIVISOR;
1621 : :
1622 : 0 : offset_vaddr = PLT_PTR_CAST(infl_req->meta);
1623 : 0 : inst->dptr = (uint64_t)dm_vaddr - pad_len;
1624 : 0 : inst->rptr = inst->dptr;
1625 : 0 : cpt_inst_w4.s.dlen = inputlen - iv_len;
1626 : : } else {
1627 : 0 : offset_vaddr = PLT_PTR_SUB(dm_vaddr, off_ctrl_len + hdr_len);
1628 : 0 : inst->dptr = (uint64_t)offset_vaddr;
1629 : : /* RPTR should just exclude offset control word */
1630 : 0 : inst->rptr = (uint64_t)PLT_PTR_SUB(dm_vaddr, hdr_len);
1631 : 0 : cpt_inst_w4.s.dlen = inputlen + off_ctrl_len;
1632 : : }
1633 : :
1634 : 0 : *offset_vaddr = offset_ctrl;
1635 : :
1636 : 0 : iv_d = ((uint8_t *)offset_vaddr + off_ctrl_len);
1637 : 0 : pdcp_iv_copy(iv_d, cipher_iv, pdcp_ci_alg, false);
1638 : :
1639 : 0 : iv_d = ((uint8_t *)offset_vaddr + off_ctrl_len + pdcp_iv_off);
1640 : 0 : pdcp_iv_copy(iv_d, auth_iv, pdcp_auth_alg, false);
1641 : :
1642 : 0 : inst->w4.u64 = cpt_inst_w4.u64;
1643 : 0 : return 0;
1644 : :
1645 : : } else {
1646 [ # # # # ]: 0 : if (is_sg_ver2)
1647 : 0 : return pdcp_chain_sg2_prep(params, se_ctx, inst, cpt_inst_w4, inputlen,
1648 : : hdr_len, offset_ctrl, req_flags, cipher_iv,
1649 : : auth_iv, false, pdcp_ci_alg, pdcp_auth_alg,
1650 : : pad_len, off_ctrl_len, use_metadata);
1651 : : else
1652 : 0 : return pdcp_chain_sg1_prep(params, se_ctx, inst, cpt_inst_w4, inputlen,
1653 : : hdr_len, offset_ctrl, req_flags, cipher_iv,
1654 : : auth_iv, false, pdcp_ci_alg, pdcp_auth_alg);
1655 : : }
1656 : : }
1657 : :
1658 : : static __rte_always_inline int
1659 : : cpt_pdcp_alg_prep(uint32_t req_flags, uint64_t d_offs, uint64_t d_lens,
1660 : : struct roc_se_fc_params *params, struct cpt_inst_s *inst,
1661 : : struct cpt_inflight_req *infl_req, const bool is_sg_ver2, const bool use_metadata)
1662 : : {
1663 : : /*
1664 : : * pdcp_iv_offset is auth_iv_offset wrt cipher_iv_offset which is
1665 : : * 16 with old microcode without ZUC 256 support
1666 : : * whereas it is 24 with new microcode which has ZUC 256.
1667 : : * So iv_len reserved is 32B for cipher and auth IVs with old microcode
1668 : : * and 48B with new microcode.
1669 : : */
1670 : 0 : const int iv_len = params->pdcp_iv_offset * 2;
1671 : : uint32_t off_ctrl_len = ROC_SE_OFF_CTRL_LEN;
1672 : : struct roc_se_ctx *se_ctx = params->ctx;
1673 : : uint32_t encr_data_len, auth_data_len;
1674 : 0 : const int flags = se_ctx->zsk_flags;
1675 : : uint32_t encr_offset, auth_offset;
1676 : : union cpt_inst_w4 cpt_inst_w4;
1677 : : uint32_t passthrough_len = 0;
1678 : : int32_t inputlen, outputlen;
1679 : : uint64_t *offset_vaddr;
1680 : : uint8_t pdcp_alg_type;
1681 : : uint32_t pad_len = 0;
1682 : : uint32_t mac_len = 0;
1683 : : uint64_t offset_ctrl;
1684 : : bool pack_iv = false;
1685 : : const uint8_t *iv_s;
1686 : : int ret;
1687 : :
1688 : 0 : mac_len = se_ctx->mac_len;
1689 : :
1690 : 0 : cpt_inst_w4.u64 = se_ctx->template_w4.u64;
1691 : : if (use_metadata)
1692 : : off_ctrl_len *= 2;
1693 : :
1694 [ # # # # : 0 : if (flags == 0x1) {
# # # # #
# ]
1695 : 0 : cpt_inst_w4.s.opcode_minor = 1;
1696 : 0 : iv_s = params->auth_iv_buf;
1697 : :
1698 : : /*
1699 : : * Microcode expects offsets in bytes
1700 : : * TODO: Rounding off
1701 : : */
1702 : : auth_data_len = ROC_SE_AUTH_DLEN(d_lens);
1703 : 0 : auth_offset = ROC_SE_AUTH_OFFSET(d_offs);
1704 : 0 : pdcp_alg_type = se_ctx->pdcp_auth_alg;
1705 : :
1706 [ # # # # : 0 : if (pdcp_alg_type != ROC_SE_PDCP_ALG_TYPE_AES_CMAC) {
# # ]
1707 : :
1708 [ # # # # ]: 0 : if (params->auth_iv_len == 25)
1709 : : pack_iv = true;
1710 : :
1711 : 0 : auth_offset = auth_offset / 8;
1712 : 0 : auth_data_len = RTE_ALIGN(auth_data_len, 8) / 8;
1713 : : }
1714 : :
1715 : : if (use_metadata) {
1716 : 0 : passthrough_len = RTE_ALIGN_CEIL(auth_offset, 8);
1717 : 0 : pad_len = passthrough_len - auth_offset;
1718 : 0 : inputlen = pad_len + iv_len + auth_offset + auth_data_len;
1719 : 0 : outputlen = pad_len + mac_len;
1720 : : } else {
1721 : : /* consider iv len */
1722 : 0 : auth_offset += iv_len;
1723 : 0 : inputlen = auth_offset + auth_data_len;
1724 : 0 : outputlen = iv_len + mac_len;
1725 : : }
1726 : :
1727 [ # # # # : 0 : offset_ctrl = rte_cpu_to_be_64((uint64_t)auth_offset);
# # # # #
# ]
1728 : 0 : cpt_inst_w4.s.param1 = auth_data_len;
1729 : :
1730 : : encr_data_len = 0;
1731 : : encr_offset = 0;
1732 : : } else {
1733 : 0 : cpt_inst_w4.s.opcode_minor = 0;
1734 : : iv_s = params->iv_buf;
1735 : 0 : pdcp_alg_type = se_ctx->pdcp_ci_alg;
1736 : :
1737 [ # # # # ]: 0 : if (params->cipher_iv_len == 25)
1738 : : pack_iv = true;
1739 : :
1740 : : /*
1741 : : * Microcode expects offsets in bytes
1742 : : * TODO: Rounding off
1743 : : */
1744 : : encr_data_len = ROC_SE_ENCR_DLEN(d_lens);
1745 : :
1746 : 0 : encr_offset = ROC_SE_ENCR_OFFSET(d_offs);
1747 : 0 : encr_offset = encr_offset / 8;
1748 : :
1749 : : if (use_metadata) {
1750 : 0 : passthrough_len = RTE_ALIGN_CEIL(encr_offset, 8);
1751 : 0 : pad_len = passthrough_len - encr_offset;
1752 : 0 : outputlen = pad_len + encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8);
1753 : 0 : inputlen = iv_len + outputlen;
1754 : : } else {
1755 : : /* consider iv len */
1756 : 0 : encr_offset += iv_len;
1757 : 0 : inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8);
1758 : : outputlen = inputlen;
1759 : : }
1760 : :
1761 : : /* iv offset is 0 */
1762 [ # # # # : 0 : offset_ctrl = rte_cpu_to_be_64((uint64_t)encr_offset);
# # # # ]
1763 : :
1764 : : auth_data_len = 0;
1765 : : auth_offset = 0;
1766 : 0 : cpt_inst_w4.s.param1 = (RTE_ALIGN(encr_data_len, 8) / 8);
1767 : : }
1768 : :
1769 [ # # # # : 0 : if (unlikely((encr_offset >> 16) || (auth_offset >> 8))) {
# # # # #
# ]
1770 : 0 : plt_dp_err("Offset not supported");
1771 : 0 : plt_dp_err("enc_offset: %d", encr_offset);
1772 : 0 : plt_dp_err("auth_offset: %d", auth_offset);
1773 : 0 : return -1;
1774 : : }
1775 : :
1776 : : /*
1777 : : * In cn9k, cn10k since we have a limitation of
1778 : : * IV & Offset control word not part of instruction
1779 : : * and need to be part of Data Buffer, we check if
1780 : : * head room is there and then only do the Direct mode processing
1781 : : */
1782 [ # # # # ]: 0 : if (likely((req_flags & ROC_SE_SINGLE_BUF_INPLACE) &&
1783 : : (req_flags & ROC_SE_SINGLE_BUF_HEADROOM))) {
1784 : :
1785 : : void *dm_vaddr = params->bufs[0].vaddr;
1786 : :
1787 : : /* Use Direct mode */
1788 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN;
1789 : :
1790 : : if (use_metadata) {
1791 : 0 : inst->w0.cn20k.pkt_ctl = META_PKT_CTL_ENABLE;
1792 : 0 : inst->meta_sz = META_LEN / META_SIZE_DIVISOR;
1793 : :
1794 : : offset_vaddr = PLT_PTR_CAST(infl_req->meta);
1795 [ # # # # ]: 0 : offset_ctrl = rte_cpu_to_be_64((uint64_t)(passthrough_len));
1796 : 0 : *offset_vaddr = offset_ctrl;
1797 : :
1798 : 0 : inst->dptr = (uint64_t)dm_vaddr - pad_len;
1799 : 0 : inst->rptr = inst->dptr;
1800 : :
1801 : 0 : cpt_inst_w4.s.dlen = inputlen - iv_len + pad_len;
1802 : : } else {
1803 : :
1804 : 0 : offset_vaddr = (uint64_t *)((uint8_t *)dm_vaddr - off_ctrl_len - iv_len);
1805 : :
1806 : : /* DPTR */
1807 : 0 : inst->dptr = (uint64_t)offset_vaddr;
1808 : : /* RPTR should just exclude offset control word */
1809 : 0 : inst->rptr = (uint64_t)dm_vaddr - iv_len;
1810 : :
1811 : 0 : cpt_inst_w4.s.dlen = inputlen + off_ctrl_len;
1812 : : }
1813 : :
1814 : 0 : uint8_t *iv_d = ((uint8_t *)offset_vaddr + off_ctrl_len);
1815 : 0 : pdcp_iv_copy(iv_d, iv_s, pdcp_alg_type, pack_iv);
1816 : :
1817 : 0 : *offset_vaddr = offset_ctrl;
1818 : 0 : inst->w4.u64 = cpt_inst_w4.u64;
1819 : : } else {
1820 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_PDCP_CHAIN | ROC_DMA_MODE_SG;
1821 [ # # ]: 0 : inst->w4.u64 = cpt_inst_w4.u64;
1822 [ # # # # : 0 : if (is_sg_ver2)
# # # # #
# ]
1823 [ # # # # : 0 : ret = sg2_inst_prep(params, inst, offset_ctrl, iv_s, iv_len, pack_iv,
# # # # ]
1824 : : pdcp_alg_type, inputlen, outputlen, 0, req_flags, 1, 0,
1825 : : off_ctrl_len, use_metadata);
1826 : : else
1827 [ # # # # : 0 : ret = sg_inst_prep(params, inst, offset_ctrl, iv_s, iv_len, pack_iv,
# # # # ]
1828 : : pdcp_alg_type, inputlen, outputlen, 0, req_flags, 1, 0);
1829 [ # # # # : 0 : if (unlikely(ret)) {
# # # # #
# ]
1830 : 0 : plt_dp_err("sg prep failed");
1831 : 0 : return -1;
1832 : : }
1833 : : }
1834 : :
1835 : : return 0;
1836 : : }
1837 : :
1838 : : static __rte_always_inline int
1839 : : cpt_kasumi_enc_prep(uint32_t req_flags, uint64_t d_offs, uint64_t d_lens,
1840 : : struct roc_se_fc_params *params, struct cpt_inst_s *inst, const bool is_sg_ver2)
1841 : : {
1842 : : uint32_t encr_data_len, auth_data_len;
1843 : : int32_t inputlen = 0, outputlen = 0;
1844 : : uint32_t encr_offset, auth_offset;
1845 : : const uint8_t *iv_s, iv_len = 8;
1846 : : union cpt_inst_w4 cpt_inst_w4;
1847 : : struct roc_se_ctx *se_ctx;
1848 : : uint64_t offset_ctrl;
1849 : : uint32_t mac_len = 0;
1850 : : uint8_t dir = 0;
1851 : : int flags;
1852 : :
1853 : 0 : encr_offset = ROC_SE_ENCR_OFFSET(d_offs) / 8;
1854 : 0 : auth_offset = ROC_SE_AUTH_OFFSET(d_offs) / 8;
1855 : 0 : encr_data_len = ROC_SE_ENCR_DLEN(d_lens);
1856 : 0 : auth_data_len = ROC_SE_AUTH_DLEN(d_lens);
1857 : :
1858 : : se_ctx = params->ctx;
1859 : 0 : flags = se_ctx->zsk_flags;
1860 : 0 : mac_len = se_ctx->mac_len;
1861 : :
1862 : 0 : cpt_inst_w4.u64 = se_ctx->template_w4.u64;
1863 : :
1864 [ # # # # : 0 : if (flags == 0x0) {
# # # # #
# ]
1865 : : iv_s = params->iv_buf;
1866 : : /* Consider IV len */
1867 : 0 : encr_offset += iv_len;
1868 : :
1869 : 0 : inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8);
1870 : : outputlen = inputlen;
1871 : : /* iv offset is 0 */
1872 [ # # # # : 0 : offset_ctrl = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
# # # # ]
1873 : : if (unlikely((encr_offset >> 16))) {
1874 : : plt_dp_err("Offset not supported");
1875 : : plt_dp_err("enc_offset: %d", encr_offset);
1876 : : return -1;
1877 : : }
1878 : : } else {
1879 : 0 : iv_s = params->auth_iv_buf;
1880 : 0 : dir = iv_s[8] & 0x1;
1881 : :
1882 : 0 : inputlen = auth_offset + (RTE_ALIGN(auth_data_len, 8) / 8);
1883 : 0 : outputlen = mac_len;
1884 : : /* iv offset is 0 */
1885 [ # # # # : 0 : offset_ctrl = rte_cpu_to_be_64((uint64_t)auth_offset);
# # # # #
# ]
1886 [ # # # # : 0 : if (unlikely((auth_offset >> 8))) {
# # # # #
# ]
1887 : 0 : plt_dp_err("Offset not supported");
1888 : 0 : plt_dp_err("auth_offset: %d", auth_offset);
1889 : 0 : return -1;
1890 : : }
1891 : : }
1892 : :
1893 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_KASUMI | ROC_DMA_MODE_SG;
1894 : :
1895 : : /* Indicate ECB/CBC, direction, CTX from CPTR, IV from DPTR */
1896 : 0 : cpt_inst_w4.s.opcode_minor =
1897 : 0 : ((1 << 6) | (se_ctx->k_ecb << 5) | (dir << 4) | (0 << 3) | (flags & 0x7));
1898 : :
1899 : 0 : cpt_inst_w4.s.param1 = encr_data_len;
1900 : 0 : cpt_inst_w4.s.param2 = auth_data_len;
1901 : :
1902 : 0 : inst->w4.u64 = cpt_inst_w4.u64;
1903 : :
1904 [ # # # # : 0 : if (unlikely(iv_s == NULL))
# # # # ]
1905 : : return -1;
1906 : :
1907 [ # # # # : 0 : if (is_sg_ver2)
# # # # ]
1908 : : sg2_inst_prep(params, inst, offset_ctrl, iv_s, iv_len, 0, 0, inputlen, outputlen, 0,
1909 : : req_flags, 0, 0, ROC_SE_OFF_CTRL_LEN, false);
1910 : : else
1911 : : sg_inst_prep(params, inst, offset_ctrl, iv_s, iv_len, 0, 0, inputlen, outputlen, 0,
1912 : : req_flags, 0, 0);
1913 : :
1914 : : return 0;
1915 : : }
1916 : :
1917 : : static __rte_always_inline int
1918 : : cpt_kasumi_dec_prep(uint64_t d_offs, uint64_t d_lens, struct roc_se_fc_params *params,
1919 : : struct cpt_inst_s *inst, const bool is_sg_ver2)
1920 : : {
1921 : : int32_t inputlen = 0, outputlen;
1922 : : struct roc_se_ctx *se_ctx;
1923 : : uint8_t iv_len = 8;
1924 : : uint32_t encr_offset;
1925 : : uint32_t encr_data_len;
1926 : : int flags;
1927 : : uint8_t dir = 0;
1928 : : union cpt_inst_w4 cpt_inst_w4;
1929 : : uint64_t offset_ctrl;
1930 : :
1931 : 0 : encr_offset = ROC_SE_ENCR_OFFSET(d_offs) / 8;
1932 : 0 : encr_data_len = ROC_SE_ENCR_DLEN(d_lens);
1933 : :
1934 : : se_ctx = params->ctx;
1935 : 0 : flags = se_ctx->zsk_flags;
1936 : :
1937 : 0 : cpt_inst_w4.u64 = 0;
1938 : 0 : cpt_inst_w4.s.opcode_major = ROC_SE_MAJOR_OP_KASUMI | ROC_DMA_MODE_SG;
1939 : :
1940 : : /* indicates ECB/CBC, direction, ctx from cptr, iv from dptr */
1941 : 0 : cpt_inst_w4.s.opcode_minor =
1942 : 0 : ((1 << 6) | (se_ctx->k_ecb << 5) | (dir << 4) | (0 << 3) | (flags & 0x7));
1943 : :
1944 : : /*
1945 : : * Lengths are expected in bits.
1946 : : */
1947 : 0 : cpt_inst_w4.s.param1 = encr_data_len;
1948 : :
1949 : : /* consider iv len */
1950 : 0 : encr_offset += iv_len;
1951 : :
1952 : 0 : inputlen = encr_offset + (RTE_ALIGN(encr_data_len, 8) / 8);
1953 : : outputlen = inputlen;
1954 : :
1955 [ # # # # ]: 0 : offset_ctrl = rte_cpu_to_be_64((uint64_t)encr_offset << 16);
1956 : : if (unlikely((encr_offset >> 16))) {
1957 : : plt_dp_err("Offset not supported");
1958 : : plt_dp_err("enc_offset: %d", encr_offset);
1959 : : return -1;
1960 : : }
1961 : :
1962 [ # # # # ]: 0 : inst->w4.u64 = cpt_inst_w4.u64;
1963 : :
1964 : : if (unlikely(params->iv_buf == NULL))
1965 : : return -1;
1966 : :
1967 [ # # # # ]: 0 : if (is_sg_ver2)
1968 : : sg2_inst_prep(params, inst, offset_ctrl, params->iv_buf, iv_len, 0, 0, inputlen,
1969 : : outputlen, 0, 0, 0, 1, ROC_SE_OFF_CTRL_LEN, false);
1970 : : else
1971 : : sg_inst_prep(params, inst, offset_ctrl, params->iv_buf, iv_len, 0, 0, inputlen,
1972 : : outputlen, 0, 0, 0, 1);
1973 : :
1974 : : return 0;
1975 : : }
1976 : :
1977 : : static __rte_always_inline int
1978 : : cpt_fc_enc_hmac_prep(uint32_t flags, uint64_t d_offs, uint64_t d_lens,
1979 : : struct roc_se_fc_params *fc_params, struct cpt_inst_s *inst,
1980 : : struct cpt_inflight_req *infl_req, const bool is_sg_ver2,
1981 : : const bool use_metadata)
1982 : : {
1983 : : struct roc_se_ctx *ctx = fc_params->ctx;
1984 : : uint8_t fc_type;
1985 : : int ret = -1;
1986 : :
1987 : 0 : fc_type = ctx->fc_type;
1988 : :
1989 [ # # # # ]: 0 : if (likely(fc_type == ROC_SE_FC_GEN)) {
1990 : : ret = cpt_enc_hmac_prep(flags, d_offs, d_lens, fc_params, inst, is_sg_ver2);
1991 [ # # # # : 0 : } else if (fc_type == ROC_SE_PDCP) {
# # ]
1992 : : ret = cpt_pdcp_alg_prep(flags, d_offs, d_lens, fc_params, inst, infl_req,
1993 : : is_sg_ver2, use_metadata);
1994 [ # # # # : 0 : } else if (fc_type == ROC_SE_KASUMI) {
# # ]
1995 : : ret = cpt_kasumi_enc_prep(flags, d_offs, d_lens, fc_params, inst, is_sg_ver2);
1996 [ # # # # : 0 : } else if (fc_type == ROC_SE_HASH_HMAC) {
# # ]
1997 [ # # # # : 0 : if (is_sg_ver2)
# # ]
1998 : : ret = cpt_digest_gen_sg_ver2_prep(flags, d_lens, fc_params, inst);
1999 : : else
2000 : : ret = cpt_digest_gen_sg_ver1_prep(flags, d_lens, fc_params, inst);
2001 : : }
2002 : :
2003 : : return ret;
2004 : : }
2005 : :
2006 : : static __rte_always_inline int
2007 : : fill_sess_aead(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
2008 : : {
2009 : : struct rte_crypto_aead_xform *aead_form;
2010 : : uint8_t aes_gcm = 0, aes_ccm = 0;
2011 : : roc_se_cipher_type enc_type = 0; /* NULL Cipher type */
2012 : : roc_se_auth_type auth_type = 0; /* NULL Auth type */
2013 : : uint32_t cipher_key_len = 0;
2014 : : aead_form = &xform->aead;
2015 : :
2016 [ # # ]: 0 : if (unlikely(sess->roc_se_ctx == NULL)) {
2017 : 0 : plt_dp_err("Session crypto context is NULL");
2018 : : return -EINVAL;
2019 : : }
2020 : :
2021 [ # # ]: 0 : if (aead_form->op == RTE_CRYPTO_AEAD_OP_ENCRYPT) {
2022 : 0 : sess->cpt_op |= ROC_SE_OP_CIPHER_ENCRYPT;
2023 : 0 : sess->cpt_op |= ROC_SE_OP_AUTH_GENERATE;
2024 [ # # ]: 0 : } else if (aead_form->op == RTE_CRYPTO_AEAD_OP_DECRYPT) {
2025 : 0 : sess->cpt_op |= ROC_SE_OP_CIPHER_DECRYPT;
2026 : 0 : sess->cpt_op |= ROC_SE_OP_AUTH_VERIFY;
2027 : : } else {
2028 : 0 : plt_dp_err("Unknown aead operation");
2029 : : return -1;
2030 : : }
2031 [ # # # # ]: 0 : switch (aead_form->algo) {
2032 : : case RTE_CRYPTO_AEAD_AES_GCM:
2033 : : enc_type = ROC_SE_AES_GCM;
2034 : : cipher_key_len = 16;
2035 : : aes_gcm = 1;
2036 : : break;
2037 : 0 : case RTE_CRYPTO_AEAD_AES_CCM:
2038 : : enc_type = ROC_SE_AES_CCM;
2039 : : cipher_key_len = 16;
2040 : : aes_ccm = 1;
2041 : 0 : break;
2042 : 0 : case RTE_CRYPTO_AEAD_CHACHA20_POLY1305:
2043 : : enc_type = ROC_SE_CHACHA20;
2044 : : auth_type = ROC_SE_POLY1305;
2045 : : cipher_key_len = 32;
2046 : 0 : sess->chacha_poly = 1;
2047 : 0 : break;
2048 : 0 : default:
2049 : 0 : plt_dp_err("Crypto: Undefined cipher algo %u specified",
2050 : : aead_form->algo);
2051 : : return -1;
2052 : : }
2053 [ # # ]: 0 : if (aead_form->key.length < cipher_key_len) {
2054 : 0 : plt_dp_err("Invalid cipher params keylen %u",
2055 : : aead_form->key.length);
2056 : : return -1;
2057 : : }
2058 : 0 : sess->zsk_flag = 0;
2059 : 0 : sess->aes_gcm = aes_gcm;
2060 : 0 : sess->aes_ccm = aes_ccm;
2061 : 0 : sess->mac_len = aead_form->digest_length;
2062 : 0 : sess->iv_offset = aead_form->iv.offset;
2063 : 0 : sess->iv_length = aead_form->iv.length;
2064 : 0 : sess->aad_length = aead_form->aad_length;
2065 : :
2066 [ # # ]: 0 : if (aes_ccm) {
2067 [ # # ]: 0 : if ((sess->iv_length < 11) || (sess->iv_length > 13)) {
2068 : 0 : plt_dp_err("Crypto: Unsupported IV length %u", sess->iv_length);
2069 : : return -1;
2070 : : }
2071 : : } else {
2072 [ # # # ]: 0 : switch (sess->iv_length) {
2073 : 0 : case 12:
2074 : 0 : sess->short_iv = 1;
2075 : : case 16:
2076 : : break;
2077 : 0 : default:
2078 : 0 : plt_dp_err("Crypto: Unsupported IV length %u", sess->iv_length);
2079 : : return -1;
2080 : : }
2081 : : }
2082 : :
2083 [ # # ]: 0 : if (unlikely(roc_se_ciph_key_set(sess->roc_se_ctx, enc_type, aead_form->key.data,
2084 : : aead_form->key.length)))
2085 : : return -1;
2086 : :
2087 [ # # ]: 0 : if (unlikely(roc_se_auth_key_set(sess->roc_se_ctx, auth_type, NULL, 0,
2088 : : aead_form->digest_length)))
2089 : : return -1;
2090 : :
2091 [ # # ]: 0 : if (enc_type == ROC_SE_CHACHA20)
2092 : 0 : sess->roc_se_ctx->template_w4.s.opcode_minor |= BIT(5);
2093 : : return 0;
2094 : : }
2095 : :
2096 : : static __rte_always_inline int
2097 : : fill_sm_sess_cipher(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
2098 : : {
2099 : : struct roc_se_sm_context *sm_ctx = &sess->roc_se_ctx->se_ctx.sm_ctx;
2100 : : struct rte_crypto_cipher_xform *c_form;
2101 : : roc_sm_cipher_type enc_type = 0;
2102 : :
2103 : : if (unlikely(sess->roc_se_ctx == NULL)) {
2104 : : plt_dp_err("Session crypto context is NULL");
2105 : : return -EINVAL;
2106 : : }
2107 : :
2108 : : c_form = &xform->cipher;
2109 : :
2110 [ # # # # : 0 : if (c_form->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
# # ]
2111 : 0 : sess->cpt_op |= ROC_SE_OP_CIPHER_ENCRYPT;
2112 : 0 : sess->roc_se_ctx->template_w4.s.opcode_minor = ROC_SE_FC_MINOR_OP_ENCRYPT;
2113 [ # # # # : 0 : } else if (c_form->op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
# # ]
2114 : 0 : sess->cpt_op |= ROC_SE_OP_CIPHER_DECRYPT;
2115 : 0 : sess->roc_se_ctx->template_w4.s.opcode_minor = ROC_SE_FC_MINOR_OP_DECRYPT;
2116 : : } else {
2117 : 0 : plt_dp_err("Unknown cipher operation");
2118 : : return -1;
2119 : : }
2120 : :
2121 : : switch (c_form->algo) {
2122 : : case RTE_CRYPTO_CIPHER_SM4_CBC:
2123 : : enc_type = ROC_SM4_CBC;
2124 : : break;
2125 : : case RTE_CRYPTO_CIPHER_SM4_ECB:
2126 : : enc_type = ROC_SM4_ECB;
2127 : : break;
2128 : : case RTE_CRYPTO_CIPHER_SM4_CTR:
2129 : : enc_type = ROC_SM4_CTR;
2130 : : break;
2131 : : case RTE_CRYPTO_CIPHER_SM4_CFB:
2132 : : enc_type = ROC_SM4_CFB;
2133 : : break;
2134 : : case RTE_CRYPTO_CIPHER_SM4_OFB:
2135 : : enc_type = ROC_SM4_OFB;
2136 : : break;
2137 : 0 : default:
2138 : 0 : plt_dp_err("Crypto: Undefined cipher algo %u specified", c_form->algo);
2139 : : return -1;
2140 : : }
2141 : :
2142 : 0 : sess->iv_offset = c_form->iv.offset;
2143 : 0 : sess->iv_length = c_form->iv.length;
2144 : :
2145 [ # # # # : 0 : if (c_form->key.length != ROC_SE_SM4_KEY_LEN) {
# # ]
2146 : 0 : plt_dp_err("Invalid cipher params keylen %u", c_form->key.length);
2147 : : return -1;
2148 : : }
2149 : :
2150 : 0 : sess->zsk_flag = 0;
2151 : 0 : sess->zs_cipher = 0;
2152 : 0 : sess->aes_gcm = 0;
2153 : 0 : sess->aes_ctr = 0;
2154 : 0 : sess->is_null = 0;
2155 : 0 : sess->is_sm4 = 1;
2156 : 0 : sess->roc_se_ctx->fc_type = ROC_SE_SM;
2157 : :
2158 : 0 : sess->roc_se_ctx->template_w4.s.opcode_major = ROC_SE_MAJOR_OP_SM;
2159 : :
2160 : 0 : memcpy(sm_ctx->encr_key, c_form->key.data, ROC_SE_SM4_KEY_LEN);
2161 : 0 : sm_ctx->enc_cipher = enc_type;
2162 : :
2163 : : return 0;
2164 : : }
2165 : :
2166 : : static __rte_always_inline int
2167 : : fill_sess_cipher(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
2168 : : {
2169 : : uint8_t zsk_flag = 0, zs_cipher = 0, aes_ctr = 0, is_null = 0;
2170 : : struct rte_crypto_cipher_xform *c_form;
2171 : : roc_se_cipher_type enc_type = 0; /* NULL Cipher type */
2172 : : uint32_t cipher_key_len = 0;
2173 : :
2174 [ # # # # ]: 0 : if (unlikely(sess->roc_se_ctx == NULL)) {
2175 : 0 : plt_dp_err("Session crypto context is NULL");
2176 : : return -EINVAL;
2177 : : }
2178 : :
2179 : : c_form = &xform->cipher;
2180 : :
2181 : 0 : if ((c_form->algo == RTE_CRYPTO_CIPHER_SM4_CBC) ||
2182 : : (c_form->algo == RTE_CRYPTO_CIPHER_SM4_ECB) ||
2183 [ # # # # : 0 : (c_form->algo == RTE_CRYPTO_CIPHER_SM4_CTR) ||
# # ]
2184 [ # # # # : 0 : (c_form->algo == RTE_CRYPTO_CIPHER_SM4_CFB) ||
# # ]
2185 : : (c_form->algo == RTE_CRYPTO_CIPHER_SM4_OFB))
2186 : : return fill_sm_sess_cipher(xform, sess);
2187 : :
2188 [ # # # # : 0 : if (c_form->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
# # ]
2189 : 0 : sess->cpt_op |= ROC_SE_OP_CIPHER_ENCRYPT;
2190 [ # # # # : 0 : else if (c_form->op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
# # ]
2191 : 0 : sess->cpt_op |= ROC_SE_OP_CIPHER_DECRYPT;
2192 [ # # # # : 0 : if (xform->next != NULL &&
# # ]
2193 [ # # # # : 0 : xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
# # ]
2194 : : /* Perform decryption followed by auth verify */
2195 : 0 : sess->roc_se_ctx->template_w4.s.opcode_minor =
2196 : : ROC_SE_FC_MINOR_OP_HMAC_FIRST;
2197 : : }
2198 : : } else {
2199 : 0 : plt_dp_err("Unknown cipher operation");
2200 : : return -1;
2201 : : }
2202 : :
2203 [ # # # # : 0 : switch (c_form->algo) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # #
# ]
2204 : : case RTE_CRYPTO_CIPHER_AES_CBC:
2205 : : enc_type = ROC_SE_AES_CBC;
2206 : : cipher_key_len = 16;
2207 : : break;
2208 : 0 : case RTE_CRYPTO_CIPHER_3DES_CBC:
2209 : : enc_type = ROC_SE_DES3_CBC;
2210 : : cipher_key_len = 24;
2211 : 0 : break;
2212 : 0 : case RTE_CRYPTO_CIPHER_DES_CBC:
2213 : : /* DES is implemented using 3DES in hardware */
2214 : : enc_type = ROC_SE_DES3_CBC;
2215 : : cipher_key_len = 8;
2216 : 0 : break;
2217 : 0 : case RTE_CRYPTO_CIPHER_AES_CTR:
2218 [ # # # # : 0 : if (sess->aes_ctr_eea2) {
# # ]
2219 : : enc_type = ROC_SE_AES_CTR_EEA2;
2220 : : } else {
2221 : : enc_type = ROC_SE_AES_CTR;
2222 : : aes_ctr = 1;
2223 : : }
2224 : : cipher_key_len = 16;
2225 : : break;
2226 : 0 : case RTE_CRYPTO_CIPHER_NULL:
2227 : : enc_type = 0;
2228 : : is_null = 1;
2229 : 0 : break;
2230 : 0 : case RTE_CRYPTO_CIPHER_KASUMI_F8:
2231 [ # # # # ]: 0 : if (sess->chained_op)
2232 : : return -ENOTSUP;
2233 [ # # # # ]: 0 : if (c_form->iv.length != 8)
2234 : : return -EINVAL;
2235 : : enc_type = ROC_SE_KASUMI_F8_ECB;
2236 : : cipher_key_len = 16;
2237 : : zsk_flag = ROC_SE_K_F8;
2238 : : zs_cipher = ROC_SE_K_F8;
2239 : : break;
2240 : 0 : case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
2241 : : enc_type = ROC_SE_SNOW3G_UEA2;
2242 : : cipher_key_len = 16;
2243 : : zsk_flag = ROC_SE_ZS_EA;
2244 : : zs_cipher = ROC_SE_ZS_EA;
2245 : 0 : break;
2246 : 0 : case RTE_CRYPTO_CIPHER_ZUC_EEA3:
2247 : : enc_type = ROC_SE_ZUC_EEA3;
2248 : 0 : cipher_key_len = c_form->key.length;
2249 : : zsk_flag = ROC_SE_ZS_EA;
2250 : : zs_cipher = ROC_SE_ZS_EA;
2251 : 0 : break;
2252 : 0 : case RTE_CRYPTO_CIPHER_AES_XTS:
2253 : : enc_type = ROC_SE_AES_XTS;
2254 : : cipher_key_len = 16;
2255 : 0 : break;
2256 : 0 : case RTE_CRYPTO_CIPHER_3DES_ECB:
2257 : : enc_type = ROC_SE_DES3_ECB;
2258 : : cipher_key_len = 24;
2259 : 0 : break;
2260 : 0 : case RTE_CRYPTO_CIPHER_AES_ECB:
2261 : : enc_type = ROC_SE_AES_ECB;
2262 : : cipher_key_len = 16;
2263 : 0 : break;
2264 : 0 : case RTE_CRYPTO_CIPHER_AES_DOCSISBPI:
2265 : : /* Set DOCSIS flag */
2266 : 0 : sess->roc_se_ctx->template_w4.s.opcode_minor |= ROC_SE_FC_MINOR_OP_DOCSIS;
2267 : : enc_type = ROC_SE_AES_DOCSISBPI;
2268 : : cipher_key_len = 16;
2269 : 0 : break;
2270 : 0 : case RTE_CRYPTO_CIPHER_DES_DOCSISBPI:
2271 : : /* Set DOCSIS flag */
2272 : 0 : sess->roc_se_ctx->template_w4.s.opcode_minor |= ROC_SE_FC_MINOR_OP_DOCSIS;
2273 : : enc_type = ROC_SE_DES_DOCSISBPI;
2274 : : cipher_key_len = 8;
2275 : 0 : break;
2276 : 0 : case RTE_CRYPTO_CIPHER_3DES_CTR:
2277 : : case RTE_CRYPTO_CIPHER_AES_F8:
2278 : : case RTE_CRYPTO_CIPHER_ARC4:
2279 : 0 : plt_dp_err("Crypto: Unsupported cipher algo %u", c_form->algo);
2280 : : return -1;
2281 : 0 : default:
2282 : 0 : plt_dp_err("Crypto: Undefined cipher algo %u specified",
2283 : : c_form->algo);
2284 : : return -1;
2285 : : }
2286 : :
2287 [ # # # # : 0 : if (c_form->key.length < cipher_key_len) {
# # ]
2288 : 0 : plt_dp_err("Invalid cipher params keylen %u",
2289 : : c_form->key.length);
2290 : : return -1;
2291 : : }
2292 : :
2293 [ # # # # : 0 : if (zsk_flag && sess->roc_se_ctx->ciph_then_auth) {
# # # # #
# ]
2294 : : struct rte_crypto_auth_xform *a_form;
2295 : 0 : a_form = &xform->next->auth;
2296 [ # # # # : 0 : if (c_form->op != RTE_CRYPTO_CIPHER_OP_DECRYPT &&
# # ]
2297 [ # # # # : 0 : a_form->op != RTE_CRYPTO_AUTH_OP_VERIFY) {
# # ]
2298 : 0 : plt_dp_err("Crypto: PDCP cipher then auth must use"
2299 : : " options: decrypt and verify");
2300 : : return -EINVAL;
2301 : : }
2302 : : }
2303 : :
2304 : 0 : sess->cipher_only = 1;
2305 : 0 : sess->zsk_flag = zsk_flag;
2306 : 0 : sess->zs_cipher = zs_cipher;
2307 : 0 : sess->aes_gcm = 0;
2308 : 0 : sess->aes_ccm = 0;
2309 : 0 : sess->aes_ctr = aes_ctr;
2310 : 0 : sess->iv_offset = c_form->iv.offset;
2311 : 0 : sess->iv_length = c_form->iv.length;
2312 : 0 : sess->is_null = is_null;
2313 : :
2314 [ # # # # : 0 : if (aes_ctr)
# # ]
2315 [ # # # # : 0 : switch (sess->iv_length) {
# # # #
# ]
2316 : 0 : case 12:
2317 : 0 : sess->short_iv = 1;
2318 : : case 16:
2319 : : break;
2320 : 0 : default:
2321 : 0 : plt_dp_err("Crypto: Unsupported IV length %u", sess->iv_length);
2322 : : return -1;
2323 : : }
2324 : :
2325 [ # # # # : 0 : if (unlikely(roc_se_ciph_key_set(sess->roc_se_ctx, enc_type, c_form->key.data,
# # ]
2326 : : c_form->key.length)))
2327 : : return -1;
2328 : :
2329 : : return 0;
2330 : : }
2331 : :
2332 : : static __rte_always_inline int
2333 : : fill_sess_auth(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
2334 : : {
2335 : : uint8_t zsk_flag = 0, zs_auth = 0, aes_gcm = 0, is_null = 0, is_sha3 = 0;
2336 : : struct rte_crypto_auth_xform *a_form;
2337 : : roc_se_auth_type auth_type = 0; /* NULL Auth type */
2338 : : uint8_t is_sm3 = 0;
2339 : :
2340 [ # # # # ]: 0 : if (unlikely(sess->roc_se_ctx == NULL)) {
2341 : 0 : plt_dp_err("Session crypto context is NULL");
2342 : : return -EINVAL;
2343 : : }
2344 : :
2345 [ # # # # : 0 : if (xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC)
# # ]
2346 : : return fill_sess_gmac(xform, sess);
2347 : :
2348 [ # # # # : 0 : if (xform->next != NULL &&
# # ]
2349 [ # # # # : 0 : xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
# # ]
2350 [ # # # # : 0 : xform->next->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
# # ]
2351 : : /* Perform auth followed by encryption */
2352 : 0 : sess->roc_se_ctx->template_w4.s.opcode_minor = ROC_SE_FC_MINOR_OP_HMAC_FIRST;
2353 : : }
2354 : :
2355 : : a_form = &xform->auth;
2356 : :
2357 [ # # # # : 0 : if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY)
# # ]
2358 : 0 : sess->cpt_op |= ROC_SE_OP_AUTH_VERIFY;
2359 [ # # # # : 0 : else if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE)
# # ]
2360 : 0 : sess->cpt_op |= ROC_SE_OP_AUTH_GENERATE;
2361 : : else {
2362 : 0 : plt_dp_err("Unknown auth operation");
2363 : : return -1;
2364 : : }
2365 : :
2366 [ # # # # : 0 : switch (a_form->algo) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# ]
2367 : : case RTE_CRYPTO_AUTH_SHA1_HMAC:
2368 : : /* Fall through */
2369 : : case RTE_CRYPTO_AUTH_SHA1:
2370 : : auth_type = ROC_SE_SHA1_TYPE;
2371 : : break;
2372 : 0 : case RTE_CRYPTO_AUTH_SHA256_HMAC:
2373 : : case RTE_CRYPTO_AUTH_SHA256:
2374 : : auth_type = ROC_SE_SHA2_SHA256;
2375 : 0 : break;
2376 : 0 : case RTE_CRYPTO_AUTH_SHA512_HMAC:
2377 : : case RTE_CRYPTO_AUTH_SHA512:
2378 : : auth_type = ROC_SE_SHA2_SHA512;
2379 : 0 : break;
2380 : : case RTE_CRYPTO_AUTH_AES_GMAC:
2381 : : auth_type = ROC_SE_GMAC_TYPE;
2382 : : aes_gcm = 1;
2383 : : break;
2384 : 0 : case RTE_CRYPTO_AUTH_SHA224_HMAC:
2385 : : case RTE_CRYPTO_AUTH_SHA224:
2386 : : auth_type = ROC_SE_SHA2_SHA224;
2387 : 0 : break;
2388 : 0 : case RTE_CRYPTO_AUTH_SHA384_HMAC:
2389 : : case RTE_CRYPTO_AUTH_SHA384:
2390 : : auth_type = ROC_SE_SHA2_SHA384;
2391 : 0 : break;
2392 : 0 : case RTE_CRYPTO_AUTH_SHA3_224_HMAC:
2393 : : case RTE_CRYPTO_AUTH_SHA3_224:
2394 : : is_sha3 = 1;
2395 : : auth_type = ROC_SE_SHA3_SHA224;
2396 : 0 : break;
2397 : 0 : case RTE_CRYPTO_AUTH_SHA3_256_HMAC:
2398 : : case RTE_CRYPTO_AUTH_SHA3_256:
2399 : : is_sha3 = 1;
2400 : : auth_type = ROC_SE_SHA3_SHA256;
2401 : 0 : break;
2402 : 0 : case RTE_CRYPTO_AUTH_SHA3_384_HMAC:
2403 : : case RTE_CRYPTO_AUTH_SHA3_384:
2404 : : is_sha3 = 1;
2405 : : auth_type = ROC_SE_SHA3_SHA384;
2406 : 0 : break;
2407 : 0 : case RTE_CRYPTO_AUTH_SHA3_512_HMAC:
2408 : : case RTE_CRYPTO_AUTH_SHA3_512:
2409 : : is_sha3 = 1;
2410 : : auth_type = ROC_SE_SHA3_SHA512;
2411 : 0 : break;
2412 : 0 : case RTE_CRYPTO_AUTH_SHAKE_128:
2413 : : is_sha3 = 1;
2414 : : auth_type = ROC_SE_SHA3_SHAKE128;
2415 : 0 : break;
2416 : 0 : case RTE_CRYPTO_AUTH_SHAKE_256:
2417 : : is_sha3 = 1;
2418 : : auth_type = ROC_SE_SHA3_SHAKE256;
2419 : 0 : break;
2420 : 0 : case RTE_CRYPTO_AUTH_MD5_HMAC:
2421 : : case RTE_CRYPTO_AUTH_MD5:
2422 : : auth_type = ROC_SE_MD5_TYPE;
2423 : 0 : break;
2424 : 0 : case RTE_CRYPTO_AUTH_KASUMI_F9:
2425 [ # # # # ]: 0 : if (sess->chained_op)
2426 : : return -ENOTSUP;
2427 : : auth_type = ROC_SE_KASUMI_F9_ECB;
2428 : : /*
2429 : : * Indicate that direction needs to be taken out
2430 : : * from end of src
2431 : : */
2432 : : zsk_flag = ROC_SE_K_F9;
2433 : : zs_auth = ROC_SE_K_F9;
2434 : : break;
2435 : 0 : case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
2436 : : auth_type = ROC_SE_SNOW3G_UIA2;
2437 : : zsk_flag = ROC_SE_ZS_IA;
2438 : : zs_auth = ROC_SE_ZS_IA;
2439 : 0 : break;
2440 : 0 : case RTE_CRYPTO_AUTH_ZUC_EIA3:
2441 : : auth_type = ROC_SE_ZUC_EIA3;
2442 : : zsk_flag = ROC_SE_ZS_IA;
2443 : : zs_auth = ROC_SE_ZS_IA;
2444 : 0 : break;
2445 : 0 : case RTE_CRYPTO_AUTH_NULL:
2446 : : auth_type = 0;
2447 : : is_null = 1;
2448 : 0 : break;
2449 : 0 : case RTE_CRYPTO_AUTH_AES_CMAC:
2450 : : auth_type = ROC_SE_AES_CMAC_EIA2;
2451 : : zsk_flag = ROC_SE_ZS_IA;
2452 : 0 : break;
2453 : 0 : case RTE_CRYPTO_AUTH_SM3:
2454 : : auth_type = ROC_SE_SM3;
2455 : : is_sm3 = 1;
2456 : 0 : break;
2457 : 0 : case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
2458 : : case RTE_CRYPTO_AUTH_AES_CBC_MAC:
2459 : 0 : plt_dp_err("Crypto: Unsupported hash algo %u", a_form->algo);
2460 : : return -1;
2461 : 0 : default:
2462 : 0 : plt_dp_err("Crypto: Undefined Hash algo %u specified",
2463 : : a_form->algo);
2464 : : return -1;
2465 : : }
2466 : :
2467 [ # # # # : 0 : if (zsk_flag && sess->roc_se_ctx->auth_then_ciph) {
# # # # #
# ]
2468 : : struct rte_crypto_cipher_xform *c_form;
2469 [ # # # # : 0 : if (xform->next != NULL) {
# # ]
2470 : : c_form = &xform->next->cipher;
2471 [ # # # # : 0 : if ((c_form != NULL) && (c_form->op != RTE_CRYPTO_CIPHER_OP_ENCRYPT) &&
# # # # #
# # # ]
2472 : : a_form->op != RTE_CRYPTO_AUTH_OP_GENERATE) {
2473 : 0 : plt_dp_err("Crypto: PDCP auth then cipher must use"
2474 : : " options: encrypt and generate");
2475 : : return -EINVAL;
2476 : : }
2477 : : }
2478 : : }
2479 : :
2480 : 0 : sess->zsk_flag = zsk_flag;
2481 : 0 : sess->zs_auth = zs_auth;
2482 : 0 : sess->aes_gcm = aes_gcm;
2483 : 0 : sess->mac_len = a_form->digest_length;
2484 : 0 : sess->is_null = is_null;
2485 : 0 : sess->is_sha3 = is_sha3;
2486 : 0 : sess->is_sm3 = is_sm3;
2487 [ # # # # : 0 : if (zsk_flag) {
# # ]
2488 : 0 : sess->auth_iv_offset = a_form->iv.offset;
2489 : 0 : sess->auth_iv_length = a_form->iv.length;
2490 : : }
2491 [ # # # # : 0 : if (unlikely(roc_se_auth_key_set(sess->roc_se_ctx, auth_type, a_form->key.data,
# # ]
2492 : : a_form->key.length, a_form->digest_length)))
2493 : : return -1;
2494 : :
2495 : : return 0;
2496 : : }
2497 : :
2498 : : static __rte_always_inline int
2499 : : fill_sess_gmac(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
2500 : : {
2501 : : struct rte_crypto_auth_xform *a_form;
2502 : : roc_se_cipher_type enc_type = 0; /* NULL Cipher type */
2503 : : roc_se_auth_type auth_type = 0; /* NULL Auth type */
2504 : :
2505 : : if (unlikely(sess->roc_se_ctx == NULL)) {
2506 : : plt_dp_err("Session crypto context is NULL");
2507 : : return -EINVAL;
2508 : : }
2509 : :
2510 : : a_form = &xform->auth;
2511 : :
2512 [ # # # # : 0 : if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE)
# # ]
2513 : 0 : sess->cpt_op |= ROC_SE_OP_ENCODE;
2514 [ # # # # : 0 : else if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY)
# # ]
2515 : 0 : sess->cpt_op |= ROC_SE_OP_DECODE;
2516 : : else {
2517 : 0 : plt_dp_err("Unknown auth operation");
2518 : : return -1;
2519 : : }
2520 : :
2521 : : switch (a_form->algo) {
2522 : : case RTE_CRYPTO_AUTH_AES_GMAC:
2523 : : enc_type = ROC_SE_AES_GCM;
2524 : : auth_type = ROC_SE_GMAC_TYPE;
2525 : : break;
2526 : : default:
2527 : : plt_dp_err("Crypto: Undefined cipher algo %u specified",
2528 : : a_form->algo);
2529 : : return -1;
2530 : : }
2531 : :
2532 : 0 : sess->zsk_flag = 0;
2533 : 0 : sess->aes_gcm = 0;
2534 : 0 : sess->is_gmac = 1;
2535 : 0 : sess->iv_offset = a_form->iv.offset;
2536 : 0 : sess->iv_length = a_form->iv.length;
2537 : 0 : sess->mac_len = a_form->digest_length;
2538 : :
2539 [ # # # # : 0 : switch (sess->iv_length) {
# # # #
# ]
2540 : 0 : case 12:
2541 : 0 : sess->short_iv = 1;
2542 : : case 16:
2543 : : break;
2544 : 0 : default:
2545 : 0 : plt_dp_err("Crypto: Unsupported IV length %u", sess->iv_length);
2546 : : return -1;
2547 : : }
2548 : :
2549 [ # # # # : 0 : if (unlikely(roc_se_ciph_key_set(sess->roc_se_ctx, enc_type, a_form->key.data,
# # ]
2550 : : a_form->key.length)))
2551 : : return -1;
2552 : :
2553 [ # # # # : 0 : if (unlikely(roc_se_auth_key_set(sess->roc_se_ctx, auth_type, NULL, 0,
# # ]
2554 : : a_form->digest_length)))
2555 : : return -1;
2556 : :
2557 : : return 0;
2558 : : }
2559 : :
2560 : : static __rte_always_inline uint32_t
2561 : : prepare_iov_from_pkt(struct rte_mbuf *pkt, struct roc_se_iov_ptr *iovec, uint32_t start_offset,
2562 : : const bool is_aead, const bool is_sg_ver2)
2563 : : {
2564 : : uint16_t index = 0;
2565 : : void *seg_data = NULL;
2566 : : int32_t seg_size = 0;
2567 : :
2568 [ # # # # : 0 : if (!pkt || (is_sg_ver2 && (pkt->data_len == 0) && !is_aead)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
2569 : 0 : iovec->buf_cnt = 0;
2570 : 0 : return 0;
2571 : : }
2572 : :
2573 [ # # # # ]: 0 : if (!start_offset) {
2574 : 0 : seg_data = rte_pktmbuf_mtod(pkt, void *);
2575 : 0 : seg_size = pkt->data_len;
2576 : : } else {
2577 [ # # # # ]: 0 : while (start_offset >= pkt->data_len) {
2578 : 0 : start_offset -= pkt->data_len;
2579 : 0 : pkt = pkt->next;
2580 : : }
2581 : :
2582 : 0 : seg_data = rte_pktmbuf_mtod_offset(pkt, void *, start_offset);
2583 : 0 : seg_size = pkt->data_len - start_offset;
2584 [ # # # # ]: 0 : if (!seg_size)
2585 : : return 1;
2586 : : }
2587 : :
2588 : : /* first seg */
2589 : 0 : iovec->bufs[index].vaddr = seg_data;
2590 : 0 : iovec->bufs[index].size = seg_size;
2591 : : index++;
2592 : 0 : pkt = pkt->next;
2593 : :
2594 [ # # # # : 0 : while (unlikely(pkt != NULL)) {
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
2595 : 0 : seg_data = rte_pktmbuf_mtod(pkt, void *);
2596 : 0 : seg_size = pkt->data_len;
2597 [ # # # # : 0 : if (!seg_size)
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
2598 : : break;
2599 : :
2600 : 0 : iovec->bufs[index].vaddr = seg_data;
2601 : 0 : iovec->bufs[index].size = seg_size;
2602 : :
2603 : 0 : index++;
2604 : :
2605 : 0 : pkt = pkt->next;
2606 : : }
2607 : :
2608 : 0 : iovec->buf_cnt = index;
2609 : 0 : return 0;
2610 : : }
2611 : :
2612 : : static __rte_always_inline void
2613 : : prepare_iov_from_pkt_inplace(struct rte_mbuf *pkt,
2614 : : struct roc_se_fc_params *param, uint32_t *flags)
2615 : : {
2616 : : uint16_t index = 0;
2617 : : void *seg_data = NULL;
2618 : : uint32_t seg_size = 0;
2619 : : struct roc_se_iov_ptr *iovec;
2620 : :
2621 : 0 : seg_data = rte_pktmbuf_mtod(pkt, void *);
2622 : 0 : seg_size = pkt->data_len;
2623 : :
2624 : : /* first seg */
2625 : 0 : if (likely(!pkt->next)) {
2626 : : uint32_t headroom;
2627 : :
2628 : 0 : *flags |= ROC_SE_SINGLE_BUF_INPLACE;
2629 : 0 : headroom = rte_pktmbuf_headroom(pkt);
2630 [ # # # # : 0 : if (likely(headroom >= CNXK_CPT_MIN_HEADROOM_REQ))
# # # # #
# # # # #
# # # # #
# ]
2631 : 0 : *flags |= ROC_SE_SINGLE_BUF_HEADROOM;
2632 : :
2633 : 0 : param->bufs[0].vaddr = seg_data;
2634 : 0 : param->bufs[0].size = seg_size;
2635 : 0 : return;
2636 : : }
2637 : : iovec = param->src_iov;
2638 : 0 : iovec->bufs[index].vaddr = seg_data;
2639 : 0 : iovec->bufs[index].size = seg_size;
2640 : : index++;
2641 : : pkt = pkt->next;
2642 : :
2643 [ # # # # : 0 : while (unlikely(pkt != NULL)) {
# # # # #
# # # # #
# # # # #
# ]
2644 : 0 : seg_data = rte_pktmbuf_mtod(pkt, void *);
2645 : 0 : seg_size = pkt->data_len;
2646 : :
2647 [ # # # # : 0 : if (!seg_size)
# # # # #
# # # # #
# # # # #
# ]
2648 : : break;
2649 : :
2650 : 0 : iovec->bufs[index].vaddr = seg_data;
2651 : 0 : iovec->bufs[index].size = seg_size;
2652 : :
2653 : 0 : index++;
2654 : :
2655 : 0 : pkt = pkt->next;
2656 : : }
2657 : :
2658 : 0 : iovec->buf_cnt = index;
2659 : 0 : return;
2660 : : }
2661 : :
2662 : : static __rte_always_inline int
2663 : : fill_sm_params(struct rte_crypto_op *cop, struct cnxk_se_sess *sess,
2664 : : struct cpt_qp_meta_info *m_info, struct cpt_inflight_req *infl_req,
2665 : : struct cpt_inst_s *inst, const bool is_sg_ver2)
2666 : : {
2667 : : struct rte_crypto_sym_op *sym_op = cop->sym;
2668 : : struct roc_se_fc_params fc_params;
2669 : : struct rte_mbuf *m_src, *m_dst;
2670 : : uint8_t cpt_op = sess->cpt_op;
2671 : : uint64_t d_offs, d_lens;
2672 : : char src[SRC_IOV_SIZE];
2673 : : char dst[SRC_IOV_SIZE];
2674 : : void *mdata = NULL;
2675 : : uint32_t flags = 0;
2676 : : int ret;
2677 : :
2678 : 0 : uint32_t ci_data_length = sym_op->cipher.data.length;
2679 : 0 : uint32_t ci_data_offset = sym_op->cipher.data.offset;
2680 : :
2681 : 0 : if (unlikely(sess->roc_se_ctx == NULL)) {
2682 : 0 : plt_dp_err("Session crypto context is NULL");
2683 : 0 : return -EINVAL;
2684 : : }
2685 : :
2686 : 0 : fc_params.cipher_iv_len = sess->iv_length;
2687 : : fc_params.auth_iv_len = 0;
2688 : : fc_params.auth_iv_buf = NULL;
2689 : : fc_params.iv_buf = NULL;
2690 : : fc_params.mac_buf.size = 0;
2691 : : fc_params.mac_buf.vaddr = 0;
2692 : :
2693 [ # # # # ]: 0 : if (likely(sess->iv_length)) {
2694 : : flags |= ROC_SE_VALID_IV_BUF;
2695 : 0 : fc_params.iv_buf = rte_crypto_op_ctod_offset(cop, uint8_t *, sess->iv_offset);
2696 : : }
2697 : :
2698 : 0 : m_src = sym_op->m_src;
2699 : 0 : m_dst = sym_op->m_dst;
2700 : :
2701 : : d_offs = ci_data_offset;
2702 : : d_offs = (d_offs << 16);
2703 : :
2704 : : d_lens = ci_data_length;
2705 : : d_lens = (d_lens << 32);
2706 : :
2707 : : fc_params.ctx = sess->roc_se_ctx;
2708 : :
2709 [ # # # # ]: 0 : if (m_dst == NULL) {
2710 [ # # # # ]: 0 : fc_params.dst_iov = fc_params.src_iov = (void *)src;
2711 : : prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags);
2712 : : } else {
2713 : : /* Out of place processing */
2714 : : fc_params.src_iov = (void *)src;
2715 [ # # # # ]: 0 : fc_params.dst_iov = (void *)dst;
2716 : :
2717 : : /* Store SG I/O in the api for reuse */
2718 : : if (prepare_iov_from_pkt(m_src, fc_params.src_iov, 0, false, is_sg_ver2)) {
2719 : : plt_dp_err("Prepare src iov failed");
2720 : : ret = -EINVAL;
2721 : : goto err_exit;
2722 : : }
2723 : :
2724 : : if (prepare_iov_from_pkt(m_dst, fc_params.dst_iov, 0, false, is_sg_ver2)) {
2725 : : plt_dp_err("Prepare dst iov failed for m_dst %p", m_dst);
2726 : : ret = -EINVAL;
2727 : : goto err_exit;
2728 : : }
2729 : : }
2730 : :
2731 : : fc_params.meta_buf.vaddr = NULL;
2732 : :
2733 [ # # # # ]: 0 : if (unlikely(!((flags & ROC_SE_SINGLE_BUF_INPLACE) &&
2734 : : (flags & ROC_SE_SINGLE_BUF_HEADROOM)))) {
2735 [ # # # # ]: 0 : mdata = alloc_op_meta(&fc_params.meta_buf, m_info->mlen, m_info->pool, infl_req);
2736 [ # # # # ]: 0 : if (mdata == NULL) {
2737 : 0 : plt_dp_err("Error allocating meta buffer for request");
2738 : 0 : return -ENOMEM;
2739 : : }
2740 : : }
2741 : :
2742 : : /* Finally prepare the instruction */
2743 : : ret = cpt_sm_prep(flags, d_offs, d_lens, &fc_params, inst, is_sg_ver2,
2744 : : !(cpt_op & ROC_SE_OP_ENCODE));
2745 : :
2746 [ # # # # ]: 0 : if (unlikely(ret)) {
2747 : 0 : plt_dp_err("Preparing request failed due to bad input arg");
2748 : 0 : goto free_mdata_and_exit;
2749 : : }
2750 : :
2751 : : return 0;
2752 : :
2753 : : free_mdata_and_exit:
2754 [ # # # # ]: 0 : if (infl_req->op_flags & CPT_OP_FLAGS_METABUF)
2755 [ # # # # ]: 0 : rte_mempool_put(m_info->pool, infl_req->mdata);
2756 : 0 : err_exit:
2757 : : return ret;
2758 : : }
2759 : :
2760 : : static __rte_always_inline int
2761 : : fill_fc_params(struct rte_crypto_op *cop, struct cnxk_se_sess *sess,
2762 : : struct cpt_qp_meta_info *m_info, struct cpt_inflight_req *infl_req,
2763 : : struct cpt_inst_s *inst, const bool is_kasumi, const bool is_aead,
2764 : : const bool is_sg_ver2)
2765 : : {
2766 : : struct rte_crypto_sym_op *sym_op = cop->sym;
2767 : : void *mdata = NULL;
2768 : : uint32_t mc_hash_off;
2769 : : uint32_t flags = 0;
2770 : : uint64_t d_offs, d_lens;
2771 : : struct rte_mbuf *m_src, *m_dst;
2772 : 0 : uint8_t cpt_op = sess->cpt_op;
2773 : : #ifdef CPT_ALWAYS_USE_SG_MODE
2774 : : uint8_t inplace = 0;
2775 : : #else
2776 : : uint8_t inplace = 1;
2777 : : #endif
2778 : : struct roc_se_fc_params fc_params;
2779 : : char src[SRC_IOV_SIZE];
2780 : : char dst[SRC_IOV_SIZE];
2781 : : uint8_t ccm_iv_buf[16];
2782 : : uint32_t iv_buf[4];
2783 : : int ret;
2784 : :
2785 : 0 : if (unlikely(sess->roc_se_ctx == NULL)) {
2786 : 0 : plt_dp_err("Session crypto context is NULL");
2787 : 0 : return -EINVAL;
2788 : : }
2789 : :
2790 : 0 : fc_params.cipher_iv_len = sess->iv_length;
2791 : 0 : fc_params.auth_iv_len = 0;
2792 : 0 : fc_params.auth_iv_buf = NULL;
2793 : 0 : fc_params.iv_buf = NULL;
2794 : 0 : fc_params.mac_buf.size = 0;
2795 : 0 : fc_params.mac_buf.vaddr = 0;
2796 : :
2797 [ # # # # : 0 : if (likely(is_kasumi || sess->iv_length)) {
# # # # ]
2798 : : flags |= ROC_SE_VALID_IV_BUF;
2799 : 0 : fc_params.iv_buf = rte_crypto_op_ctod_offset(cop, uint8_t *, sess->iv_offset);
2800 [ # # # # : 0 : if (sess->short_iv) {
# # # # #
# # # ]
2801 : : memcpy((uint8_t *)iv_buf,
2802 : : rte_crypto_op_ctod_offset(cop, uint8_t *, sess->iv_offset), 12);
2803 : 0 : iv_buf[3] = rte_cpu_to_be_32(0x1);
2804 : 0 : fc_params.iv_buf = iv_buf;
2805 : : }
2806 [ # # # # : 0 : if (sess->aes_ccm) {
# # # # #
# # # ]
2807 : 0 : memcpy((uint8_t *)ccm_iv_buf,
2808 : : rte_crypto_op_ctod_offset(cop, uint8_t *, sess->iv_offset),
2809 : 0 : sess->iv_length + 1);
2810 : 0 : ccm_iv_buf[0] = 14 - sess->iv_length;
2811 : 0 : fc_params.iv_buf = ccm_iv_buf;
2812 : : }
2813 : : }
2814 : :
2815 : : /* Kasumi would need SG mode */
2816 : : if (is_kasumi)
2817 : : inplace = 0;
2818 : :
2819 : 0 : m_src = sym_op->m_src;
2820 : 0 : m_dst = sym_op->m_dst;
2821 : :
2822 : : if (is_aead) {
2823 : : struct rte_mbuf *m;
2824 : : uint8_t *aad_data;
2825 : : uint16_t aad_len;
2826 : :
2827 : 0 : d_offs = sym_op->aead.data.offset;
2828 : 0 : d_lens = sym_op->aead.data.length;
2829 : 0 : mc_hash_off =
2830 : : sym_op->aead.data.offset + sym_op->aead.data.length;
2831 : :
2832 : 0 : aad_data = sym_op->aead.aad.data;
2833 : 0 : aad_len = sess->aad_length;
2834 [ # # # # : 0 : if (likely((aad_len == 0) ||
# # # # ]
2835 : : ((aad_data + aad_len) ==
2836 : : rte_pktmbuf_mtod_offset(m_src, uint8_t *, sym_op->aead.data.offset)))) {
2837 : 0 : d_offs = (d_offs - aad_len) | (d_offs << 16);
2838 : 0 : d_lens = (d_lens + aad_len) | (d_lens << 32);
2839 : : } else {
2840 : : /* For AES CCM, AAD is written 18B after aad.data as per API */
2841 [ # # # # ]: 0 : if (sess->aes_ccm)
2842 : 0 : fc_params.aad_buf.vaddr = PLT_PTR_ADD(sym_op->aead.aad.data, 18);
2843 : : else
2844 : 0 : fc_params.aad_buf.vaddr = sym_op->aead.aad.data;
2845 : 0 : fc_params.aad_buf.size = aad_len;
2846 : 0 : flags |= ROC_SE_VALID_AAD_BUF;
2847 : : inplace = 0;
2848 : 0 : d_offs = d_offs << 16;
2849 : 0 : d_lens = d_lens << 32;
2850 : : }
2851 : :
2852 : 0 : m = cpt_m_dst_get(cpt_op, m_src, m_dst);
2853 : :
2854 : : /* Digest immediately following data is best case */
2855 [ # # # # ]: 0 : if (unlikely(rte_pktmbuf_mtod_offset(m, uint8_t *, mc_hash_off) !=
2856 : : (uint8_t *)sym_op->aead.digest.data)) {
2857 : 0 : flags |= ROC_SE_VALID_MAC_BUF;
2858 : 0 : fc_params.mac_buf.size = sess->mac_len;
2859 : 0 : fc_params.mac_buf.vaddr = sym_op->aead.digest.data;
2860 : : inplace = 0;
2861 : : }
2862 : : } else {
2863 : 0 : uint32_t ci_data_length = sym_op->cipher.data.length;
2864 : 0 : uint32_t ci_data_offset = sym_op->cipher.data.offset;
2865 : 0 : uint32_t a_data_length = sym_op->auth.data.length;
2866 : 0 : uint32_t a_data_offset = sym_op->auth.data.offset;
2867 : : struct roc_se_ctx *ctx = sess->roc_se_ctx;
2868 : :
2869 : 0 : const uint8_t op_minor = ctx->template_w4.s.opcode_minor;
2870 : :
2871 : 0 : d_offs = ci_data_offset;
2872 : 0 : d_offs = (d_offs << 16) | a_data_offset;
2873 : :
2874 : 0 : d_lens = ci_data_length;
2875 : 0 : d_lens = (d_lens << 32) | a_data_length;
2876 : :
2877 [ # # # # : 0 : if (likely(sess->mac_len)) {
# # # # ]
2878 : 0 : struct rte_mbuf *m = cpt_m_dst_get(cpt_op, m_src, m_dst);
2879 : :
2880 [ # # # # : 0 : if (sess->auth_first)
# # # # ]
2881 : 0 : mc_hash_off = a_data_offset + a_data_length;
2882 : : else
2883 : 0 : mc_hash_off = ci_data_offset + ci_data_length;
2884 : :
2885 : 0 : if (mc_hash_off < (a_data_offset + a_data_length))
2886 : : mc_hash_off = (a_data_offset + a_data_length);
2887 : :
2888 : : /* hmac immediately following data is best case */
2889 [ # # # # : 0 : if (!(op_minor & ROC_SE_FC_MINOR_OP_HMAC_FIRST) &&
# # # # ]
2890 [ # # # # : 0 : (unlikely(rte_pktmbuf_mtod_offset(m, uint8_t *, mc_hash_off) !=
# # # # ]
2891 : : (uint8_t *)sym_op->auth.digest.data))) {
2892 : 0 : flags |= ROC_SE_VALID_MAC_BUF;
2893 : 0 : fc_params.mac_buf.size = sess->mac_len;
2894 : : fc_params.mac_buf.vaddr =
2895 : : sym_op->auth.digest.data;
2896 : : inplace = 0;
2897 : : }
2898 : : }
2899 : : }
2900 : 0 : fc_params.ctx = sess->roc_se_ctx;
2901 : :
2902 [ # # # # : 0 : if (!(sess->auth_first) && unlikely(sess->is_null || sess->cpt_op == ROC_SE_OP_DECODE))
# # # # #
# # # # #
# # # # #
# # # #
# ]
2903 : : inplace = 0;
2904 : :
2905 [ # # # # : 0 : if (likely(!m_dst && inplace)) {
# # # # ]
2906 : : /* Case of single buffer without AAD buf or
2907 : : * separate mac buf in place and
2908 : : * not air crypto
2909 : : */
2910 [ # # # # : 0 : fc_params.dst_iov = fc_params.src_iov = (void *)src;
# # # # ]
2911 : :
2912 : : prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags);
2913 : :
2914 : : } else {
2915 : : /* Out of place processing */
2916 : 0 : fc_params.src_iov = (void *)src;
2917 [ # # # # : 0 : fc_params.dst_iov = (void *)dst;
# # # # ]
2918 : :
2919 : : /* Store SG I/O in the api for reuse */
2920 : : if (prepare_iov_from_pkt(m_src, fc_params.src_iov, 0, is_aead, is_sg_ver2)) {
2921 : : plt_dp_err("Prepare src iov failed");
2922 : : ret = -EINVAL;
2923 : : goto err_exit;
2924 : : }
2925 : :
2926 [ # # # # : 0 : if (unlikely(m_dst != NULL)) {
# # # # #
# # # ]
2927 : : if (prepare_iov_from_pkt(m_dst, fc_params.dst_iov, 0, is_aead,
2928 : : is_sg_ver2)) {
2929 : : plt_dp_err("Prepare dst iov failed for "
2930 : : "m_dst %p",
2931 : : m_dst);
2932 : : ret = -EINVAL;
2933 : : goto err_exit;
2934 : : }
2935 : : } else {
2936 : 0 : fc_params.dst_iov = (void *)src;
2937 : : }
2938 : : }
2939 : :
2940 : 0 : fc_params.meta_buf.vaddr = NULL;
2941 [ # # # # : 0 : if (unlikely(is_kasumi || !((flags & ROC_SE_SINGLE_BUF_INPLACE) &&
# # # # ]
2942 : : (flags & ROC_SE_SINGLE_BUF_HEADROOM)))) {
2943 [ # # # # : 0 : mdata = alloc_op_meta(&fc_params.meta_buf, m_info->mlen, m_info->pool, infl_req);
# # # # #
# # # ]
2944 [ # # # # : 0 : if (mdata == NULL) {
# # # # #
# # # ]
2945 : 0 : plt_dp_err("Error allocating meta buffer for request");
2946 : 0 : return -ENOMEM;
2947 : : }
2948 : : }
2949 : :
2950 : : /* Finally prepare the instruction */
2951 : :
2952 : : if (is_kasumi) {
2953 [ # # # # ]: 0 : if (cpt_op & ROC_SE_OP_ENCODE)
2954 : : ret = cpt_kasumi_enc_prep(flags, d_offs, d_lens, &fc_params, inst,
2955 : : is_sg_ver2);
2956 : : else
2957 : : ret = cpt_kasumi_dec_prep(d_offs, d_lens, &fc_params, inst, is_sg_ver2);
2958 : : } else {
2959 [ # # # # : 0 : if (cpt_op & ROC_SE_OP_ENCODE)
# # # # ]
2960 : : ret = cpt_enc_hmac_prep(flags, d_offs, d_lens, &fc_params, inst,
2961 : : is_sg_ver2);
2962 : : else
2963 : : ret = cpt_dec_hmac_prep(flags, d_offs, d_lens, &fc_params, inst,
2964 : : is_sg_ver2);
2965 : : }
2966 : :
2967 [ # # # # : 0 : if (unlikely(ret)) {
# # # # #
# # # ]
2968 : 0 : plt_dp_err("Preparing request failed due to bad input arg");
2969 : 0 : goto free_mdata_and_exit;
2970 : : }
2971 : :
2972 : : return 0;
2973 : :
2974 : : free_mdata_and_exit:
2975 [ # # # # : 0 : if (infl_req->op_flags & CPT_OP_FLAGS_METABUF)
# # # # #
# # # ]
2976 [ # # # # : 0 : rte_mempool_put(m_info->pool, infl_req->mdata);
# # # # #
# # # ]
2977 : 0 : err_exit:
2978 : : return ret;
2979 : : }
2980 : :
2981 : : static inline int
2982 : 0 : fill_passthrough_params(struct rte_crypto_op *cop, struct cpt_inst_s *inst)
2983 : : {
2984 : : struct rte_crypto_sym_op *sym_op = cop->sym;
2985 : : struct rte_mbuf *m_src, *m_dst;
2986 : :
2987 : : const union cpt_inst_w4 w4 = {
2988 : : .s.opcode_major = ROC_SE_MAJOR_OP_MISC,
2989 : : .s.opcode_minor = ROC_SE_MISC_MINOR_OP_PASSTHROUGH,
2990 : : .s.param1 = 1,
2991 : : .s.param2 = 1,
2992 : : .s.dlen = 0,
2993 : : };
2994 : :
2995 : 0 : m_src = sym_op->m_src;
2996 : 0 : m_dst = sym_op->m_dst;
2997 : :
2998 [ # # ]: 0 : if (unlikely(m_dst != NULL && m_dst != m_src)) {
2999 : 0 : void *src = rte_pktmbuf_mtod_offset(m_src, void *, cop->sym->cipher.data.offset);
3000 : 0 : void *dst = rte_pktmbuf_mtod(m_dst, void *);
3001 : 0 : int data_len = cop->sym->cipher.data.length;
3002 : :
3003 [ # # ]: 0 : rte_memcpy(dst, src, data_len);
3004 : : }
3005 : :
3006 : 0 : inst->w0.u64 = 0;
3007 : 0 : inst->w5.u64 = 0;
3008 : 0 : inst->w6.u64 = 0;
3009 : 0 : inst->w4.u64 = w4.u64;
3010 : :
3011 : 0 : return 0;
3012 : : }
3013 : :
3014 : : static __rte_always_inline int
3015 : : fill_pdcp_params(struct rte_crypto_op *cop, struct cnxk_se_sess *sess,
3016 : : struct cpt_qp_meta_info *m_info, struct cpt_inflight_req *infl_req,
3017 : : struct cpt_inst_s *inst, const bool is_sg_ver2, const bool use_metadata)
3018 : : {
3019 : : struct rte_crypto_sym_op *sym_op = cop->sym;
3020 : : struct roc_se_fc_params fc_params;
3021 : : uint32_t c_data_len, c_data_off;
3022 : : struct rte_mbuf *m_src, *m_dst;
3023 : : uint64_t d_offs, d_lens;
3024 : : char src[SRC_IOV_SIZE];
3025 : : char dst[SRC_IOV_SIZE];
3026 : : void *mdata = NULL;
3027 : : uint32_t flags = 0;
3028 : : int ret;
3029 : :
3030 : 0 : if (unlikely(sess->roc_se_ctx == NULL)) {
3031 : 0 : plt_dp_err("Session crypto context is NULL");
3032 : 0 : return -EINVAL;
3033 : : }
3034 : :
3035 : : /* Cipher only */
3036 : :
3037 : 0 : fc_params.cipher_iv_len = sess->iv_length;
3038 : : fc_params.auth_iv_len = 0;
3039 : : fc_params.iv_buf = NULL;
3040 : : fc_params.auth_iv_buf = NULL;
3041 : 0 : fc_params.pdcp_iv_offset = sess->roc_se_ctx->pdcp_iv_offset;
3042 : :
3043 [ # # # # ]: 0 : if (likely(sess->iv_length))
3044 : 0 : fc_params.iv_buf = rte_crypto_op_ctod_offset(cop, uint8_t *, sess->iv_offset);
3045 : :
3046 : 0 : m_src = sym_op->m_src;
3047 : 0 : m_dst = sym_op->m_dst;
3048 : :
3049 : 0 : c_data_len = sym_op->cipher.data.length;
3050 : 0 : c_data_off = sym_op->cipher.data.offset;
3051 : :
3052 : : d_offs = (uint64_t)c_data_off << 16;
3053 : : d_lens = (uint64_t)c_data_len << 32;
3054 : :
3055 : : fc_params.ctx = sess->roc_se_ctx;
3056 : :
3057 [ # # # # ]: 0 : if (likely(m_dst == NULL || m_src == m_dst)) {
3058 [ # # # # ]: 0 : fc_params.dst_iov = fc_params.src_iov = (void *)src;
3059 : : prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags);
3060 : : } else {
3061 : : /* Out of place processing */
3062 : :
3063 : : fc_params.src_iov = (void *)src;
3064 [ # # # # ]: 0 : fc_params.dst_iov = (void *)dst;
3065 : :
3066 : : /* Store SG I/O in the api for reuse */
3067 : : if (unlikely(
3068 : : prepare_iov_from_pkt(m_src, fc_params.src_iov, 0, false, is_sg_ver2))) {
3069 : : plt_dp_err("Prepare src iov failed");
3070 : : ret = -EINVAL;
3071 : : goto err_exit;
3072 : : }
3073 : :
3074 : : if (unlikely(
3075 : : prepare_iov_from_pkt(m_dst, fc_params.dst_iov, 0, false, is_sg_ver2))) {
3076 : : plt_dp_err("Prepare dst iov failed for m_dst %p", m_dst);
3077 : : ret = -EINVAL;
3078 : : goto err_exit;
3079 : : }
3080 : : }
3081 : :
3082 : : fc_params.meta_buf.vaddr = NULL;
3083 [ # # # # ]: 0 : if (unlikely(!((flags & ROC_SE_SINGLE_BUF_INPLACE) &&
3084 : : (flags & ROC_SE_SINGLE_BUF_HEADROOM)))) {
3085 [ # # # # ]: 0 : mdata = alloc_op_meta(&fc_params.meta_buf, m_info->mlen, m_info->pool, infl_req);
3086 [ # # # # ]: 0 : if (mdata == NULL) {
3087 : 0 : plt_dp_err("Could not allocate meta buffer");
3088 : : ret = -ENOMEM;
3089 : 0 : goto err_exit;
3090 : : }
3091 : : }
3092 : :
3093 : : ret = cpt_pdcp_alg_prep(flags, d_offs, d_lens, &fc_params, inst, infl_req, is_sg_ver2,
3094 : : use_metadata);
3095 [ # # # # ]: 0 : if (unlikely(ret)) {
3096 : 0 : plt_dp_err("Could not prepare instruction");
3097 : 0 : goto free_mdata_and_exit;
3098 : : }
3099 : :
3100 : : return 0;
3101 : :
3102 : : free_mdata_and_exit:
3103 [ # # # # ]: 0 : if (infl_req->op_flags & CPT_OP_FLAGS_METABUF)
3104 [ # # # # ]: 0 : rte_mempool_put(m_info->pool, infl_req->mdata);
3105 : 0 : err_exit:
3106 : : return ret;
3107 : : }
3108 : :
3109 : : static __rte_always_inline int
3110 : : fill_pdcp_chain_params(struct rte_crypto_op *cop, struct cnxk_se_sess *sess,
3111 : : struct cpt_qp_meta_info *m_info, struct cpt_inflight_req *infl_req,
3112 : : struct cpt_inst_s *inst, const bool is_sg_ver2, const bool use_metadata)
3113 : : {
3114 : : uint32_t ci_data_length, ci_data_offset, a_data_length, a_data_offset;
3115 : 0 : struct rte_crypto_sym_op *sym_op = cop->sym;
3116 : 0 : struct roc_se_fc_params fc_params = { };
3117 : : struct rte_mbuf *m_src, *m_dst;
3118 : 0 : uint8_t cpt_op = sess->cpt_op;
3119 : : uint64_t d_offs, d_lens;
3120 : : char src[SRC_IOV_SIZE];
3121 : : char dst[SRC_IOV_SIZE];
3122 : 0 : bool inplace = true;
3123 : 0 : uint32_t flags = 0;
3124 : : void *mdata;
3125 : : int ret;
3126 : :
3127 : 0 : if (unlikely(sess->roc_se_ctx == NULL)) {
3128 : 0 : plt_dp_err("Session crypto context is NULL");
3129 : 0 : return -EINVAL;
3130 : : }
3131 : :
3132 : 0 : fc_params.cipher_iv_len = sess->iv_length;
3133 : 0 : fc_params.auth_iv_len = sess->auth_iv_length;
3134 : : fc_params.iv_buf = NULL;
3135 : : fc_params.auth_iv_buf = NULL;
3136 : 0 : fc_params.pdcp_iv_offset = sess->roc_se_ctx->pdcp_iv_offset;
3137 : :
3138 : 0 : m_src = sym_op->m_src;
3139 : 0 : m_dst = sym_op->m_dst;
3140 : :
3141 [ # # # # ]: 0 : if (likely(sess->iv_length))
3142 : 0 : fc_params.iv_buf = rte_crypto_op_ctod_offset(cop, uint8_t *, sess->iv_offset);
3143 : :
3144 : 0 : ci_data_length = sym_op->cipher.data.length;
3145 : 0 : ci_data_offset = sym_op->cipher.data.offset;
3146 : 0 : a_data_length = sym_op->auth.data.length;
3147 : 0 : a_data_offset = sym_op->auth.data.offset;
3148 : :
3149 : : /*
3150 : : * For ZUC & SNOW, length & offset is provided in bits. Convert to
3151 : : * bytes.
3152 : : */
3153 : :
3154 [ # # # # ]: 0 : if (sess->zs_cipher) {
3155 : 0 : ci_data_length /= 8;
3156 : 0 : ci_data_offset /= 8;
3157 : : }
3158 : :
3159 [ # # # # ]: 0 : if (sess->zs_auth) {
3160 : 0 : a_data_length /= 8;
3161 : 0 : a_data_offset /= 8;
3162 : : /*
3163 : : * ZUC & SNOW would have valid iv_buf. AES-CMAC doesn't require
3164 : : * IV from application.
3165 : : */
3166 : 0 : fc_params.auth_iv_buf =
3167 : 0 : rte_crypto_op_ctod_offset(cop, uint8_t *, sess->auth_iv_offset);
3168 : : #ifdef CNXK_CRYPTODEV_DEBUG
3169 : : if (sess->auth_iv_length == 0)
3170 : : plt_err("Invalid auth IV length");
3171 : : #endif
3172 : : }
3173 : :
3174 : 0 : d_offs = ci_data_offset;
3175 : 0 : d_offs = (d_offs << 16) | a_data_offset;
3176 : 0 : d_lens = ci_data_length;
3177 : 0 : d_lens = (d_lens << 32) | a_data_length;
3178 : :
3179 [ # # # # ]: 0 : if (likely(sess->mac_len)) {
3180 : 0 : struct rte_mbuf *m = cpt_m_dst_get(cpt_op, m_src, m_dst);
3181 : :
3182 : 0 : cpt_digest_buf_lb_check(sess, m, &fc_params, &flags, sym_op, &inplace,
3183 : : a_data_offset, a_data_length, ci_data_offset,
3184 : : ci_data_length, true);
3185 : : }
3186 : :
3187 : 0 : fc_params.ctx = sess->roc_se_ctx;
3188 : :
3189 [ # # # # : 0 : if (likely((m_dst == NULL || m_dst == m_src)) && inplace) {
# # # # ]
3190 [ # # # # ]: 0 : fc_params.dst_iov = fc_params.src_iov = (void *)src;
3191 : : prepare_iov_from_pkt_inplace(m_src, &fc_params, &flags);
3192 : : } else {
3193 : : /* Out of place processing */
3194 : 0 : fc_params.src_iov = (void *)src;
3195 [ # # # # ]: 0 : fc_params.dst_iov = (void *)dst;
3196 : :
3197 : : /* Store SG I/O in the api for reuse */
3198 : : if (unlikely(
3199 : : prepare_iov_from_pkt(m_src, fc_params.src_iov, 0, false, is_sg_ver2))) {
3200 : : plt_dp_err("Could not prepare src iov");
3201 : : ret = -EINVAL;
3202 : : goto err_exit;
3203 : : }
3204 : :
3205 [ # # # # ]: 0 : if (unlikely(m_dst != NULL)) {
3206 : : if (unlikely(prepare_iov_from_pkt(m_dst, fc_params.dst_iov, 0, false,
3207 : : is_sg_ver2))) {
3208 : : plt_dp_err("Could not prepare m_dst iov %p", m_dst);
3209 : : ret = -EINVAL;
3210 : : goto err_exit;
3211 : : }
3212 : : } else {
3213 : 0 : fc_params.dst_iov = (void *)src;
3214 : : }
3215 : : }
3216 : :
3217 [ # # # # ]: 0 : if (unlikely(!((flags & ROC_SE_SINGLE_BUF_INPLACE) &&
3218 : : (flags & ROC_SE_SINGLE_BUF_HEADROOM)))) {
3219 [ # # # # ]: 0 : mdata = alloc_op_meta(&fc_params.meta_buf, m_info->mlen, m_info->pool, infl_req);
3220 [ # # # # ]: 0 : if (unlikely(mdata == NULL)) {
3221 : 0 : plt_dp_err("Could not allocate meta buffer for request");
3222 : 0 : return -ENOMEM;
3223 : : }
3224 : : }
3225 : :
3226 : : /* Finally prepare the instruction */
3227 [ # # # # ]: 0 : ret = cpt_pdcp_chain_alg_prep(flags, d_offs, d_lens, &fc_params, inst, infl_req, is_sg_ver2,
3228 : : use_metadata);
3229 [ # # # # ]: 0 : if (unlikely(ret)) {
3230 : 0 : plt_dp_err("Could not prepare instruction");
3231 : 0 : goto free_mdata_and_exit;
3232 : : }
3233 : :
3234 : : return 0;
3235 : :
3236 : : free_mdata_and_exit:
3237 [ # # # # ]: 0 : if (infl_req->op_flags & CPT_OP_FLAGS_METABUF)
3238 [ # # # # ]: 0 : rte_mempool_put(m_info->pool, infl_req->mdata);
3239 : 0 : err_exit:
3240 : : return ret;
3241 : : }
3242 : :
3243 : : static __rte_always_inline void
3244 : : compl_auth_verify(struct rte_crypto_op *op, uint8_t *gen_mac, uint64_t mac_len)
3245 : : {
3246 : : uint8_t *mac;
3247 : : struct rte_crypto_sym_op *sym_op = op->sym;
3248 : :
3249 [ # # ]: 0 : if (sym_op->auth.digest.data)
3250 : : mac = sym_op->auth.digest.data;
3251 : : else
3252 : 0 : mac = rte_pktmbuf_mtod_offset(sym_op->m_src, uint8_t *,
3253 : : sym_op->auth.data.length +
3254 : : sym_op->auth.data.offset);
3255 [ # # ]: 0 : if (!mac) {
3256 : 0 : op->status = RTE_CRYPTO_OP_STATUS_ERROR;
3257 : 0 : return;
3258 : : }
3259 : :
3260 [ # # ]: 0 : if (memcmp(mac, gen_mac, mac_len))
3261 : 0 : op->status = RTE_CRYPTO_OP_STATUS_AUTH_FAILED;
3262 : : else
3263 : : op->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
3264 : : }
3265 : :
3266 : : static __rte_always_inline void
3267 : : find_kasumif9_direction_and_length(uint8_t *src, uint32_t counter_num_bytes,
3268 : : uint32_t *addr_length_in_bits,
3269 : : uint8_t *addr_direction)
3270 : : {
3271 : : uint8_t found = 0;
3272 : : uint32_t pos;
3273 : : uint8_t last_byte;
3274 [ # # # # ]: 0 : while (!found && counter_num_bytes > 0) {
3275 : 0 : counter_num_bytes--;
3276 [ # # # # ]: 0 : if (src[counter_num_bytes] == 0x00)
3277 : 0 : continue;
3278 : 0 : pos = rte_bsf32(src[counter_num_bytes]);
3279 [ # # # # ]: 0 : if (pos == 7) {
3280 [ # # # # ]: 0 : if (likely(counter_num_bytes > 0)) {
3281 : 0 : last_byte = src[counter_num_bytes - 1];
3282 : 0 : *addr_direction = last_byte & 0x1;
3283 : : *addr_length_in_bits =
3284 : 0 : counter_num_bytes * 8 - 1;
3285 : : }
3286 : : } else {
3287 : 0 : last_byte = src[counter_num_bytes];
3288 : 0 : *addr_direction = (last_byte >> (pos + 1)) & 0x1;
3289 : : *addr_length_in_bits =
3290 : 0 : counter_num_bytes * 8 + (8 - (pos + 2));
3291 : : }
3292 : : found = 1;
3293 : : }
3294 : : }
3295 : :
3296 : : /*
3297 : : * This handles all auth only except AES_GMAC
3298 : : */
3299 : : static __rte_always_inline int
3300 : : fill_digest_params(struct rte_crypto_op *cop, struct cnxk_se_sess *sess,
3301 : : struct cpt_qp_meta_info *m_info, struct cpt_inflight_req *infl_req,
3302 : : struct cpt_inst_s *inst, const bool is_sg_ver2, const bool use_metadata)
3303 : : {
3304 : : uint32_t space = 0;
3305 : : struct rte_crypto_sym_op *sym_op = cop->sym;
3306 : : void *mdata;
3307 : : uint32_t auth_range_off;
3308 : : uint32_t flags = 0;
3309 : : uint64_t d_offs = 0, d_lens;
3310 : : struct rte_mbuf *m_src, *m_dst;
3311 : 0 : uint16_t auth_op = sess->cpt_op & ROC_SE_OP_AUTH_MASK;
3312 : 0 : uint16_t mac_len = sess->mac_len;
3313 : : struct roc_se_fc_params params;
3314 : : char src[SRC_IOV_SIZE];
3315 : : uint8_t iv_buf[16];
3316 : : int ret;
3317 : :
3318 : 0 : if (unlikely(sess->roc_se_ctx == NULL)) {
3319 : 0 : plt_dp_err("Session crypto context is NULL");
3320 : 0 : return -EINVAL;
3321 : : }
3322 : :
3323 : : memset(¶ms, 0, sizeof(struct roc_se_fc_params));
3324 : :
3325 : 0 : m_src = sym_op->m_src;
3326 : :
3327 [ # # # # ]: 0 : mdata = alloc_op_meta(¶ms.meta_buf, m_info->mlen, m_info->pool,
3328 : : infl_req);
3329 [ # # # # ]: 0 : if (mdata == NULL) {
3330 : : ret = -ENOMEM;
3331 : 0 : goto err_exit;
3332 : : }
3333 : :
3334 : 0 : auth_range_off = sym_op->auth.data.offset;
3335 : :
3336 : : flags = ROC_SE_VALID_MAC_BUF;
3337 : 0 : params.src_iov = (void *)src;
3338 [ # # # # ]: 0 : if (unlikely(sess->zsk_flag)) {
3339 : : /*
3340 : : * Since for Zuc, Kasumi, Snow3g offsets are in bits
3341 : : * we will send pass through even for auth only case,
3342 : : * let MC handle it
3343 : : */
3344 : 0 : d_offs = auth_range_off;
3345 : : auth_range_off = 0;
3346 : 0 : params.auth_iv_len = sess->auth_iv_length;
3347 : 0 : params.auth_iv_buf =
3348 : 0 : rte_crypto_op_ctod_offset(cop, uint8_t *, sess->auth_iv_offset);
3349 : 0 : params.pdcp_iv_offset = sess->roc_se_ctx->pdcp_iv_offset;
3350 [ # # # # ]: 0 : if (sess->zsk_flag == ROC_SE_K_F9) {
3351 : : uint32_t length_in_bits, num_bytes;
3352 : : uint8_t *src, direction = 0;
3353 : :
3354 : : memcpy(iv_buf,
3355 : 0 : rte_pktmbuf_mtod(cop->sym->m_src, uint8_t *), 8);
3356 : : /*
3357 : : * This is kasumi f9, take direction from
3358 : : * source buffer
3359 : : */
3360 : 0 : length_in_bits = cop->sym->auth.data.length;
3361 : 0 : num_bytes = (length_in_bits >> 3);
3362 : 0 : src = rte_pktmbuf_mtod(cop->sym->m_src, uint8_t *);
3363 : : find_kasumif9_direction_and_length(
3364 : : src, num_bytes, &length_in_bits, &direction);
3365 : 0 : length_in_bits -= 64;
3366 : 0 : cop->sym->auth.data.offset += 64;
3367 : 0 : d_offs = cop->sym->auth.data.offset;
3368 : 0 : auth_range_off = d_offs / 8;
3369 : 0 : cop->sym->auth.data.length = length_in_bits;
3370 : :
3371 : : /* Store it at end of auth iv */
3372 : 0 : iv_buf[8] = direction;
3373 : 0 : params.auth_iv_buf = iv_buf;
3374 : : }
3375 : : }
3376 : :
3377 : 0 : d_lens = sym_op->auth.data.length;
3378 : :
3379 : 0 : params.ctx = sess->roc_se_ctx;
3380 : :
3381 [ # # # # ]: 0 : if (auth_op == ROC_SE_OP_AUTH_GENERATE) {
3382 [ # # # # ]: 0 : if (sym_op->auth.digest.data) {
3383 : : /*
3384 : : * Digest to be generated
3385 : : * in separate buffer
3386 : : */
3387 : 0 : params.mac_buf.size = sess->mac_len;
3388 : 0 : params.mac_buf.vaddr = sym_op->auth.digest.data;
3389 : : } else {
3390 : 0 : uint32_t off = sym_op->auth.data.offset +
3391 : : sym_op->auth.data.length;
3392 : : int32_t dlen, space;
3393 : :
3394 [ # # # # ]: 0 : m_dst = sym_op->m_dst ? sym_op->m_dst : sym_op->m_src;
3395 : 0 : dlen = rte_pktmbuf_pkt_len(m_dst);
3396 : :
3397 : 0 : space = off + mac_len - dlen;
3398 [ # # # # ]: 0 : if (space > 0)
3399 [ # # # # ]: 0 : if (!rte_pktmbuf_append(m_dst, space)) {
3400 : 0 : plt_dp_err("Failed to extend "
3401 : : "mbuf by %uB",
3402 : : space);
3403 : : ret = -EINVAL;
3404 : 0 : goto free_mdata_and_exit;
3405 : : }
3406 : :
3407 : 0 : params.mac_buf.vaddr =
3408 : 0 : rte_pktmbuf_mtod_offset(m_dst, void *, off);
3409 : 0 : params.mac_buf.size = mac_len;
3410 : : }
3411 : : } else {
3412 : : uint64_t *op = mdata;
3413 : :
3414 : : /* Need space for storing generated mac */
3415 : : space += 2 * sizeof(uint64_t);
3416 : :
3417 : 0 : params.mac_buf.vaddr = (uint8_t *)mdata + space;
3418 : 0 : params.mac_buf.size = mac_len;
3419 : 0 : space += RTE_ALIGN_CEIL(mac_len, 8);
3420 : 0 : op[0] = (uintptr_t)params.mac_buf.vaddr;
3421 : 0 : op[1] = mac_len;
3422 : 0 : infl_req->op_flags |= CPT_OP_FLAGS_AUTH_VERIFY;
3423 : : }
3424 : :
3425 : 0 : params.meta_buf.vaddr = (uint8_t *)mdata + space;
3426 [ # # # # ]: 0 : params.meta_buf.size -= space;
3427 : :
3428 : : /* Out of place processing */
3429 : : params.src_iov = (void *)src;
3430 : :
3431 : : /*Store SG I/O in the api for reuse */
3432 : : if (prepare_iov_from_pkt(m_src, params.src_iov, auth_range_off, false, is_sg_ver2)) {
3433 : 0 : plt_dp_err("Prepare src iov failed");
3434 : : ret = -EINVAL;
3435 : 0 : goto free_mdata_and_exit;
3436 : : }
3437 : :
3438 : : ret = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, ¶ms, inst, infl_req, is_sg_ver2,
3439 : : use_metadata);
3440 : :
3441 [ # # # # ]: 0 : if (ret)
3442 : 0 : goto free_mdata_and_exit;
3443 : :
3444 : : return 0;
3445 : :
3446 : 0 : free_mdata_and_exit:
3447 [ # # # # ]: 0 : if (infl_req->op_flags & CPT_OP_FLAGS_METABUF)
3448 [ # # # # ]: 0 : rte_mempool_put(m_info->pool, infl_req->mdata);
3449 : 0 : err_exit:
3450 : : return ret;
3451 : : }
3452 : :
3453 : : static __rte_always_inline int __rte_hot
3454 : : cpt_sym_inst_fill(struct cnxk_cpt_qp *qp, struct rte_crypto_op *op, struct cnxk_se_sess *sess,
3455 : : struct cpt_inflight_req *infl_req, struct cpt_inst_s *inst, const bool is_sg_ver2,
3456 : : const bool use_metadata)
3457 : : {
3458 : : enum cpt_dp_thread_type dp_thr_type;
3459 : : int ret;
3460 : :
3461 : 0 : dp_thr_type = sess->dp_thr_type;
3462 : :
3463 : : /*
3464 : : * With cipher only, microcode expects that cipher length is non-zero. To accept such
3465 : : * instructions, send to CPT as passthrough.
3466 : : */
3467 [ # # # # : 0 : if (unlikely(sess->cipher_only && op->sym->cipher.data.length == 0))
# # # # ]
3468 : : dp_thr_type = CPT_DP_THREAD_TYPE_PT;
3469 : :
3470 [ # # # # : 0 : switch (dp_thr_type) {
# # # # #
# # # # #
# # # # ]
3471 : 0 : case CPT_DP_THREAD_TYPE_PT:
3472 : 0 : ret = fill_passthrough_params(op, inst);
3473 : 0 : break;
3474 [ # # # # ]: 0 : case CPT_DP_THREAD_TYPE_PDCP:
3475 : : ret = fill_pdcp_params(op, sess, &qp->meta_info, infl_req, inst, is_sg_ver2,
3476 : : use_metadata);
3477 : 0 : break;
3478 [ # # # # ]: 0 : case CPT_DP_THREAD_TYPE_FC_CHAIN:
3479 : : ret = fill_fc_params(op, sess, &qp->meta_info, infl_req, inst, false, false,
3480 : : is_sg_ver2);
3481 : 0 : break;
3482 [ # # # # ]: 0 : case CPT_DP_THREAD_TYPE_FC_AEAD:
3483 : : ret = fill_fc_params(op, sess, &qp->meta_info, infl_req, inst, false, true,
3484 : : is_sg_ver2);
3485 : 0 : break;
3486 [ # # # # ]: 0 : case CPT_DP_THREAD_TYPE_PDCP_CHAIN:
3487 : : ret = fill_pdcp_chain_params(op, sess, &qp->meta_info, infl_req, inst, is_sg_ver2,
3488 : : use_metadata);
3489 : 0 : break;
3490 [ # # # # ]: 0 : case CPT_DP_THREAD_TYPE_KASUMI:
3491 : : ret = fill_fc_params(op, sess, &qp->meta_info, infl_req, inst, true, false,
3492 : : is_sg_ver2);
3493 : 0 : break;
3494 [ # # # # ]: 0 : case CPT_DP_THREAD_TYPE_SM:
3495 : : ret = fill_sm_params(op, sess, &qp->meta_info, infl_req, inst, is_sg_ver2);
3496 : 0 : break;
3497 : :
3498 [ # # # # ]: 0 : case CPT_DP_THREAD_AUTH_ONLY:
3499 : : ret = fill_digest_params(op, sess, &qp->meta_info, infl_req, inst, is_sg_ver2,
3500 : : use_metadata);
3501 : 0 : break;
3502 : : default:
3503 : : ret = -EINVAL;
3504 : : }
3505 : :
3506 : : return ret;
3507 : : }
3508 : :
3509 : : static __rte_always_inline uint32_t
3510 : : prepare_iov_from_raw_vec(struct rte_crypto_vec *vec, struct roc_se_iov_ptr *iovec, uint32_t num)
3511 : : {
3512 : : uint32_t i, total_len = 0;
3513 : :
3514 [ # # # # : 0 : for (i = 0; i < num; i++) {
# # # # #
# ]
3515 : 0 : iovec->bufs[i].vaddr = vec[i].base;
3516 : 0 : iovec->bufs[i].size = vec[i].len;
3517 : :
3518 : 0 : total_len += vec[i].len;
3519 : : }
3520 : :
3521 : 0 : iovec->buf_cnt = i;
3522 : 0 : return total_len;
3523 : : }
3524 : :
3525 : : static __rte_always_inline void
3526 : : cnxk_raw_burst_to_iov(struct rte_crypto_sym_vec *vec, union rte_crypto_sym_ofs *ofs, int index,
3527 : : struct cnxk_iov *iov)
3528 : : {
3529 : 0 : iov->iv_buf = vec->iv[index].va;
3530 : 0 : iov->aad_buf = vec->aad[index].va;
3531 : 0 : iov->mac_buf = vec->digest[index].va;
3532 : :
3533 : 0 : iov->data_len =
3534 : 0 : prepare_iov_from_raw_vec(vec->src_sgl[index].vec, (struct roc_se_iov_ptr *)iov->src,
3535 : 0 : vec->src_sgl[index].num);
3536 : :
3537 [ # # ]: 0 : if (vec->dest_sgl == NULL)
3538 : : prepare_iov_from_raw_vec(vec->src_sgl[index].vec, (struct roc_se_iov_ptr *)iov->dst,
3539 : : vec->src_sgl[index].num);
3540 : : else
3541 : 0 : prepare_iov_from_raw_vec(vec->dest_sgl[index].vec,
3542 : : (struct roc_se_iov_ptr *)iov->dst,
3543 : 0 : vec->dest_sgl[index].num);
3544 : :
3545 : 0 : iov->c_head = ofs->ofs.cipher.head;
3546 : 0 : iov->c_tail = ofs->ofs.cipher.tail;
3547 : :
3548 : 0 : iov->a_head = ofs->ofs.auth.head;
3549 : 0 : iov->a_tail = ofs->ofs.auth.tail;
3550 : : }
3551 : :
3552 : : static __rte_always_inline void
3553 : : cnxk_raw_to_iov(struct rte_crypto_vec *data_vec, uint16_t n_vecs, union rte_crypto_sym_ofs *ofs,
3554 : : struct rte_crypto_va_iova_ptr *iv, struct rte_crypto_va_iova_ptr *digest,
3555 : : struct rte_crypto_va_iova_ptr *aad, struct cnxk_iov *iov)
3556 : : {
3557 : 0 : iov->iv_buf = iv->va;
3558 : 0 : iov->aad_buf = aad->va;
3559 : 0 : iov->mac_buf = digest->va;
3560 : :
3561 : 0 : iov->data_len =
3562 : 0 : prepare_iov_from_raw_vec(data_vec, (struct roc_se_iov_ptr *)iov->src, n_vecs);
3563 : : prepare_iov_from_raw_vec(data_vec, (struct roc_se_iov_ptr *)iov->dst, n_vecs);
3564 : :
3565 : 0 : iov->c_head = ofs->ofs.cipher.head;
3566 : 0 : iov->c_tail = ofs->ofs.cipher.tail;
3567 : :
3568 : 0 : iov->a_head = ofs->ofs.auth.head;
3569 [ # # ]: 0 : iov->a_tail = ofs->ofs.auth.tail;
3570 : : }
3571 : :
3572 : : static inline void
3573 : 0 : raw_memcpy(struct cnxk_iov *iov)
3574 : : {
3575 : : struct roc_se_iov_ptr *src = (struct roc_se_iov_ptr *)iov->src;
3576 : : struct roc_se_iov_ptr *dst = (struct roc_se_iov_ptr *)iov->dst;
3577 : 0 : int num = src->buf_cnt;
3578 : : int i;
3579 : :
3580 : : /* skip copy in case of inplace */
3581 [ # # ]: 0 : if (dst->bufs[0].vaddr == src->bufs[0].vaddr)
3582 : : return;
3583 : :
3584 [ # # ]: 0 : for (i = 0; i < num; i++) {
3585 [ # # ]: 0 : rte_memcpy(dst->bufs[i].vaddr, src->bufs[i].vaddr, src->bufs[i].size);
3586 : 0 : dst->bufs[i].size = src->bufs[i].size;
3587 : : }
3588 : : }
3589 : :
3590 : : static inline int
3591 : 0 : fill_raw_passthrough_params(struct cnxk_iov *iov, struct cpt_inst_s *inst)
3592 : : {
3593 : : const union cpt_inst_w4 w4 = {
3594 : : .s.opcode_major = ROC_SE_MAJOR_OP_MISC,
3595 : : .s.opcode_minor = ROC_SE_MISC_MINOR_OP_PASSTHROUGH,
3596 : : .s.param1 = 1,
3597 : : .s.param2 = 1,
3598 : : .s.dlen = 0,
3599 : : };
3600 : :
3601 : 0 : inst->w0.u64 = 0;
3602 : 0 : inst->w5.u64 = 0;
3603 : 0 : inst->w4.u64 = w4.u64;
3604 : :
3605 : 0 : raw_memcpy(iov);
3606 : :
3607 : 0 : return 0;
3608 : : }
3609 : :
3610 : : static __rte_always_inline int
3611 : : fill_raw_fc_params(struct cnxk_iov *iov, struct cnxk_se_sess *sess, struct cpt_qp_meta_info *m_info,
3612 : : struct cpt_inflight_req *infl_req, struct cpt_inst_s *inst, const bool is_kasumi,
3613 : : const bool is_aead, const bool is_sg_ver2)
3614 : : {
3615 : : uint32_t cipher_len, auth_len = 0;
3616 : : struct roc_se_fc_params fc_params;
3617 : 0 : uint8_t cpt_op = sess->cpt_op;
3618 : : uint64_t d_offs, d_lens;
3619 : : uint8_t ccm_iv_buf[16];
3620 : : uint32_t flags = 0;
3621 : : void *mdata = NULL;
3622 : : uint32_t iv_buf[4];
3623 : : int ret;
3624 : :
3625 [ # # # # ]: 0 : if (unlikely(sess->roc_se_ctx == NULL)) {
3626 : 0 : plt_dp_err("Session crypto context is NULL");
3627 : 0 : return -EINVAL;
3628 : : }
3629 : :
3630 : 0 : fc_params.cipher_iv_len = sess->iv_length;
3631 : 0 : fc_params.ctx = sess->roc_se_ctx;
3632 : 0 : fc_params.auth_iv_buf = NULL;
3633 : 0 : fc_params.auth_iv_len = 0;
3634 : 0 : fc_params.mac_buf.size = 0;
3635 : 0 : fc_params.mac_buf.vaddr = 0;
3636 : 0 : fc_params.iv_buf = NULL;
3637 : :
3638 [ # # # # ]: 0 : if (likely(sess->iv_length)) {
3639 : : flags |= ROC_SE_VALID_IV_BUF;
3640 : :
3641 [ # # # # ]: 0 : if (sess->is_gmac) {
3642 : 0 : fc_params.iv_buf = iov->aad_buf;
3643 [ # # # # ]: 0 : if (sess->short_iv) {
3644 : : memcpy((void *)iv_buf, iov->aad_buf, 12);
3645 : 0 : iv_buf[3] = rte_cpu_to_be_32(0x1);
3646 : 0 : fc_params.iv_buf = iv_buf;
3647 : : }
3648 : : } else {
3649 : 0 : fc_params.iv_buf = iov->iv_buf;
3650 [ # # # # ]: 0 : if (sess->short_iv) {
3651 : : memcpy((void *)iv_buf, iov->iv_buf, 12);
3652 : 0 : iv_buf[3] = rte_cpu_to_be_32(0x1);
3653 : 0 : fc_params.iv_buf = iv_buf;
3654 : : }
3655 : : }
3656 : :
3657 [ # # # # ]: 0 : if (sess->aes_ccm) {
3658 : 0 : memcpy((uint8_t *)ccm_iv_buf, iov->iv_buf, sess->iv_length + 1);
3659 : 0 : ccm_iv_buf[0] = 14 - sess->iv_length;
3660 : 0 : fc_params.iv_buf = ccm_iv_buf;
3661 : : }
3662 : : }
3663 : :
3664 : 0 : fc_params.src_iov = (void *)iov->src;
3665 : 0 : fc_params.dst_iov = (void *)iov->dst;
3666 : :
3667 : 0 : cipher_len = iov->data_len - iov->c_head - iov->c_tail;
3668 : 0 : auth_len = iov->data_len - iov->a_head - iov->a_tail;
3669 : :
3670 : 0 : d_offs = (iov->c_head << 16) | iov->a_head;
3671 : 0 : d_lens = ((uint64_t)cipher_len << 32) | auth_len;
3672 : :
3673 : : if (is_aead) {
3674 : 0 : uint16_t aad_len = sess->aad_length;
3675 : :
3676 [ # # ]: 0 : if (likely(aad_len == 0)) {
3677 : 0 : d_offs = (iov->c_head << 16) | iov->c_head;
3678 : 0 : d_lens = ((uint64_t)cipher_len << 32) | cipher_len;
3679 : : } else {
3680 : 0 : flags |= ROC_SE_VALID_AAD_BUF;
3681 : 0 : fc_params.aad_buf.size = sess->aad_length;
3682 : : /* For AES CCM, AAD is written 18B after aad.data as per API */
3683 [ # # ]: 0 : if (sess->aes_ccm)
3684 : 0 : fc_params.aad_buf.vaddr = PLT_PTR_ADD((uint8_t *)iov->aad_buf, 18);
3685 : : else
3686 : 0 : fc_params.aad_buf.vaddr = iov->aad_buf;
3687 : :
3688 : 0 : d_offs = (iov->c_head << 16);
3689 : : d_lens = ((uint64_t)cipher_len << 32);
3690 : : }
3691 : : }
3692 : :
3693 [ # # # # ]: 0 : if (likely(sess->mac_len)) {
3694 : 0 : flags |= ROC_SE_VALID_MAC_BUF;
3695 : 0 : fc_params.mac_buf.size = sess->mac_len;
3696 : 0 : fc_params.mac_buf.vaddr = iov->mac_buf;
3697 : : }
3698 : :
3699 : 0 : fc_params.meta_buf.vaddr = NULL;
3700 [ # # # # ]: 0 : mdata = alloc_op_meta(&fc_params.meta_buf, m_info->mlen, m_info->pool, infl_req);
3701 [ # # # # ]: 0 : if (mdata == NULL) {
3702 : 0 : plt_dp_err("Error allocating meta buffer for request");
3703 : 0 : return -ENOMEM;
3704 : : }
3705 : :
3706 : : if (is_kasumi) {
3707 : : if (cpt_op & ROC_SE_OP_ENCODE)
3708 : : ret = cpt_enc_hmac_prep(flags, d_offs, d_lens, &fc_params, inst,
3709 : : is_sg_ver2);
3710 : : else
3711 : : ret = cpt_dec_hmac_prep(flags, d_offs, d_lens, &fc_params, inst,
3712 : : is_sg_ver2);
3713 : : } else {
3714 [ # # # # ]: 0 : if (cpt_op & ROC_SE_OP_ENCODE)
3715 : : ret = cpt_enc_hmac_prep(flags, d_offs, d_lens, &fc_params, inst,
3716 : : is_sg_ver2);
3717 : : else
3718 : : ret = cpt_dec_hmac_prep(flags, d_offs, d_lens, &fc_params, inst,
3719 : : is_sg_ver2);
3720 : : }
3721 : :
3722 [ # # # # ]: 0 : if (unlikely(ret)) {
3723 : 0 : plt_dp_err("Preparing request failed due to bad input arg");
3724 : 0 : goto free_mdata_and_exit;
3725 : : }
3726 : :
3727 : : return 0;
3728 : :
3729 : : free_mdata_and_exit:
3730 [ # # # # ]: 0 : rte_mempool_put(m_info->pool, infl_req->mdata);
3731 : 0 : return ret;
3732 : : }
3733 : :
3734 : : static __rte_always_inline int
3735 : : fill_raw_digest_params(struct cnxk_iov *iov, struct cnxk_se_sess *sess,
3736 : : struct cpt_qp_meta_info *m_info, struct cpt_inflight_req *infl_req,
3737 : : struct cpt_inst_s *inst, const bool is_sg_ver2, const bool use_metadata)
3738 : : {
3739 : 0 : uint16_t auth_op = sess->cpt_op & ROC_SE_OP_AUTH_MASK;
3740 : : struct roc_se_fc_params fc_params;
3741 [ # # ]: 0 : uint16_t mac_len = sess->mac_len;
3742 : : uint64_t d_offs, d_lens;
3743 : : uint32_t auth_len = 0;
3744 : : uint32_t flags = 0;
3745 : : void *mdata = NULL;
3746 : : uint32_t space = 0;
3747 : : int ret;
3748 : :
3749 : : memset(&fc_params, 0, sizeof(struct roc_se_fc_params));
3750 : 0 : fc_params.cipher_iv_len = sess->iv_length;
3751 : 0 : fc_params.ctx = sess->roc_se_ctx;
3752 : :
3753 [ # # ]: 0 : if (unlikely(sess->roc_se_ctx == NULL)) {
3754 : 0 : plt_dp_err("Session crypto context is NULL");
3755 : 0 : return -EINVAL;
3756 : : }
3757 : :
3758 [ # # ]: 0 : mdata = alloc_op_meta(&fc_params.meta_buf, m_info->mlen, m_info->pool, infl_req);
3759 [ # # ]: 0 : if (mdata == NULL) {
3760 : 0 : plt_dp_err("Error allocating meta buffer for request");
3761 : : ret = -ENOMEM;
3762 : 0 : goto err_exit;
3763 : : }
3764 : :
3765 : : flags |= ROC_SE_VALID_MAC_BUF;
3766 : 0 : fc_params.src_iov = (void *)iov->src;
3767 : 0 : auth_len = iov->data_len - iov->a_head - iov->a_tail;
3768 : : d_lens = auth_len;
3769 : 0 : d_offs = iov->a_head;
3770 : :
3771 [ # # ]: 0 : if (auth_op == ROC_SE_OP_AUTH_GENERATE) {
3772 : 0 : fc_params.mac_buf.size = sess->mac_len;
3773 : 0 : fc_params.mac_buf.vaddr = iov->mac_buf;
3774 : : } else {
3775 : : uint64_t *op = mdata;
3776 : :
3777 : : /* Need space for storing generated mac */
3778 : : space += 2 * sizeof(uint64_t);
3779 : :
3780 : 0 : fc_params.mac_buf.vaddr = (uint8_t *)mdata + space;
3781 : 0 : fc_params.mac_buf.size = mac_len;
3782 : 0 : space += RTE_ALIGN_CEIL(mac_len, 8);
3783 : 0 : op[0] = (uintptr_t)iov->mac_buf;
3784 : 0 : op[1] = mac_len;
3785 : 0 : infl_req->op_flags |= CPT_OP_FLAGS_AUTH_VERIFY;
3786 : : }
3787 : :
3788 : 0 : fc_params.meta_buf.vaddr = (uint8_t *)mdata + space;
3789 [ # # ]: 0 : fc_params.meta_buf.size -= space;
3790 : :
3791 : : ret = cpt_fc_enc_hmac_prep(flags, d_offs, d_lens, &fc_params, inst, infl_req, is_sg_ver2,
3792 : : use_metadata);
3793 [ # # ]: 0 : if (ret)
3794 : 0 : goto free_mdata_and_exit;
3795 : :
3796 : : return 0;
3797 : :
3798 : : free_mdata_and_exit:
3799 [ # # ]: 0 : if (infl_req->op_flags & CPT_OP_FLAGS_METABUF)
3800 [ # # ]: 0 : rte_mempool_put(m_info->pool, infl_req->mdata);
3801 : 0 : err_exit:
3802 : : return ret;
3803 : : }
3804 : :
3805 : : #endif /*_CNXK_SE_H_ */
|