1*492a19a0SVikas Gupta /* SPDX-License-Identifier: BSD-3-Clause
2*492a19a0SVikas Gupta * Copyright(c) 2020 Broadcom
3*492a19a0SVikas Gupta * All rights reserved.
4*492a19a0SVikas Gupta */
5*492a19a0SVikas Gupta
6*492a19a0SVikas Gupta #include <stdbool.h>
7*492a19a0SVikas Gupta
8*492a19a0SVikas Gupta #include <rte_byteorder.h>
9*492a19a0SVikas Gupta #include <rte_crypto_sym.h>
10*492a19a0SVikas Gupta #include <rte_cryptodev.h>
11*492a19a0SVikas Gupta #include <rte_mbuf.h>
12*492a19a0SVikas Gupta #include <rte_mempool.h>
13*492a19a0SVikas Gupta
14*492a19a0SVikas Gupta #include "bcmfs_sym_defs.h"
15*492a19a0SVikas Gupta #include "bcmfs_sym_engine.h"
16*492a19a0SVikas Gupta #include "bcmfs_sym_req.h"
17*492a19a0SVikas Gupta #include "bcmfs_sym_session.h"
18*492a19a0SVikas Gupta
19*492a19a0SVikas Gupta /** Process cipher operation */
20*492a19a0SVikas Gupta static int
process_crypto_cipher_op(struct rte_crypto_op * op,struct rte_mbuf * mbuf_src,struct rte_mbuf * mbuf_dst,struct bcmfs_sym_session * sess,struct bcmfs_sym_request * req)21*492a19a0SVikas Gupta process_crypto_cipher_op(struct rte_crypto_op *op,
22*492a19a0SVikas Gupta struct rte_mbuf *mbuf_src,
23*492a19a0SVikas Gupta struct rte_mbuf *mbuf_dst,
24*492a19a0SVikas Gupta struct bcmfs_sym_session *sess,
25*492a19a0SVikas Gupta struct bcmfs_sym_request *req)
26*492a19a0SVikas Gupta {
27*492a19a0SVikas Gupta int rc = 0;
28*492a19a0SVikas Gupta struct fsattr src, dst, iv, key;
29*492a19a0SVikas Gupta struct rte_crypto_sym_op *sym_op = op->sym;
30*492a19a0SVikas Gupta
31*492a19a0SVikas Gupta fsattr_sz(&src) = sym_op->cipher.data.length;
32*492a19a0SVikas Gupta fsattr_sz(&dst) = sym_op->cipher.data.length;
33*492a19a0SVikas Gupta
34*492a19a0SVikas Gupta fsattr_va(&src) = rte_pktmbuf_mtod_offset
35*492a19a0SVikas Gupta (mbuf_src,
36*492a19a0SVikas Gupta uint8_t *,
37*492a19a0SVikas Gupta op->sym->cipher.data.offset);
38*492a19a0SVikas Gupta
39*492a19a0SVikas Gupta fsattr_va(&dst) = rte_pktmbuf_mtod_offset
40*492a19a0SVikas Gupta (mbuf_dst,
41*492a19a0SVikas Gupta uint8_t *,
42*492a19a0SVikas Gupta op->sym->cipher.data.offset);
43*492a19a0SVikas Gupta
44*492a19a0SVikas Gupta fsattr_pa(&src) = rte_pktmbuf_iova(mbuf_src);
45*492a19a0SVikas Gupta fsattr_pa(&dst) = rte_pktmbuf_iova(mbuf_dst);
46*492a19a0SVikas Gupta
47*492a19a0SVikas Gupta fsattr_va(&iv) = rte_crypto_op_ctod_offset(op,
48*492a19a0SVikas Gupta uint8_t *,
49*492a19a0SVikas Gupta sess->cipher.iv.offset);
50*492a19a0SVikas Gupta
51*492a19a0SVikas Gupta fsattr_sz(&iv) = sess->cipher.iv.length;
52*492a19a0SVikas Gupta
53*492a19a0SVikas Gupta fsattr_va(&key) = sess->cipher.key.data;
54*492a19a0SVikas Gupta fsattr_pa(&key) = 0;
55*492a19a0SVikas Gupta fsattr_sz(&key) = sess->cipher.key.length;
56*492a19a0SVikas Gupta
57*492a19a0SVikas Gupta rc = bcmfs_crypto_build_cipher_req(req, sess->cipher.algo,
58*492a19a0SVikas Gupta sess->cipher.op, &src,
59*492a19a0SVikas Gupta &dst, &key, &iv);
60*492a19a0SVikas Gupta if (rc)
61*492a19a0SVikas Gupta op->status = RTE_CRYPTO_OP_STATUS_ERROR;
62*492a19a0SVikas Gupta
63*492a19a0SVikas Gupta return rc;
64*492a19a0SVikas Gupta }
65*492a19a0SVikas Gupta
66*492a19a0SVikas Gupta /** Process auth operation */
67*492a19a0SVikas Gupta static int
process_crypto_auth_op(struct rte_crypto_op * op,struct rte_mbuf * mbuf_src,struct bcmfs_sym_session * sess,struct bcmfs_sym_request * req)68*492a19a0SVikas Gupta process_crypto_auth_op(struct rte_crypto_op *op,
69*492a19a0SVikas Gupta struct rte_mbuf *mbuf_src,
70*492a19a0SVikas Gupta struct bcmfs_sym_session *sess,
71*492a19a0SVikas Gupta struct bcmfs_sym_request *req)
72*492a19a0SVikas Gupta {
73*492a19a0SVikas Gupta int rc = 0;
74*492a19a0SVikas Gupta struct fsattr src, dst, mac, key, iv;
75*492a19a0SVikas Gupta
76*492a19a0SVikas Gupta fsattr_sz(&src) = op->sym->auth.data.length;
77*492a19a0SVikas Gupta fsattr_va(&src) = rte_pktmbuf_mtod_offset(mbuf_src,
78*492a19a0SVikas Gupta uint8_t *,
79*492a19a0SVikas Gupta op->sym->auth.data.offset);
80*492a19a0SVikas Gupta fsattr_pa(&src) = rte_pktmbuf_iova(mbuf_src);
81*492a19a0SVikas Gupta
82*492a19a0SVikas Gupta if (!sess->auth.op) {
83*492a19a0SVikas Gupta fsattr_va(&mac) = op->sym->auth.digest.data;
84*492a19a0SVikas Gupta fsattr_pa(&mac) = op->sym->auth.digest.phys_addr;
85*492a19a0SVikas Gupta fsattr_sz(&mac) = sess->auth.digest_length;
86*492a19a0SVikas Gupta } else {
87*492a19a0SVikas Gupta fsattr_va(&dst) = op->sym->auth.digest.data;
88*492a19a0SVikas Gupta fsattr_pa(&dst) = op->sym->auth.digest.phys_addr;
89*492a19a0SVikas Gupta fsattr_sz(&dst) = sess->auth.digest_length;
90*492a19a0SVikas Gupta }
91*492a19a0SVikas Gupta
92*492a19a0SVikas Gupta fsattr_va(&key) = sess->auth.key.data;
93*492a19a0SVikas Gupta fsattr_pa(&key) = 0;
94*492a19a0SVikas Gupta fsattr_sz(&key) = sess->auth.key.length;
95*492a19a0SVikas Gupta
96*492a19a0SVikas Gupta /* AES-GMAC uses AES-GCM-128 authenticator */
97*492a19a0SVikas Gupta if (sess->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
98*492a19a0SVikas Gupta fsattr_va(&iv) = rte_crypto_op_ctod_offset(op,
99*492a19a0SVikas Gupta uint8_t *,
100*492a19a0SVikas Gupta sess->auth.iv.offset);
101*492a19a0SVikas Gupta fsattr_pa(&iv) = 0;
102*492a19a0SVikas Gupta fsattr_sz(&iv) = sess->auth.iv.length;
103*492a19a0SVikas Gupta } else {
104*492a19a0SVikas Gupta fsattr_va(&iv) = NULL;
105*492a19a0SVikas Gupta fsattr_sz(&iv) = 0;
106*492a19a0SVikas Gupta }
107*492a19a0SVikas Gupta
108*492a19a0SVikas Gupta rc = bcmfs_crypto_build_auth_req(req, sess->auth.algo,
109*492a19a0SVikas Gupta sess->auth.op,
110*492a19a0SVikas Gupta &src,
111*492a19a0SVikas Gupta (sess->auth.op) ? (&dst) : NULL,
112*492a19a0SVikas Gupta (sess->auth.op) ? NULL : (&mac),
113*492a19a0SVikas Gupta &key, &iv);
114*492a19a0SVikas Gupta
115*492a19a0SVikas Gupta if (rc)
116*492a19a0SVikas Gupta op->status = RTE_CRYPTO_OP_STATUS_ERROR;
117*492a19a0SVikas Gupta
118*492a19a0SVikas Gupta return rc;
119*492a19a0SVikas Gupta }
120*492a19a0SVikas Gupta
121*492a19a0SVikas Gupta /** Process combined/chained mode operation */
122*492a19a0SVikas Gupta static int
process_crypto_combined_op(struct rte_crypto_op * op,struct rte_mbuf * mbuf_src,struct rte_mbuf * mbuf_dst,struct bcmfs_sym_session * sess,struct bcmfs_sym_request * req)123*492a19a0SVikas Gupta process_crypto_combined_op(struct rte_crypto_op *op,
124*492a19a0SVikas Gupta struct rte_mbuf *mbuf_src,
125*492a19a0SVikas Gupta struct rte_mbuf *mbuf_dst,
126*492a19a0SVikas Gupta struct bcmfs_sym_session *sess,
127*492a19a0SVikas Gupta struct bcmfs_sym_request *req)
128*492a19a0SVikas Gupta {
129*492a19a0SVikas Gupta int rc = 0, aad_size = 0;
130*492a19a0SVikas Gupta struct fsattr src, dst, iv;
131*492a19a0SVikas Gupta struct rte_crypto_sym_op *sym_op = op->sym;
132*492a19a0SVikas Gupta struct fsattr cipher_key, aad, mac, auth_key;
133*492a19a0SVikas Gupta
134*492a19a0SVikas Gupta fsattr_sz(&src) = sym_op->cipher.data.length;
135*492a19a0SVikas Gupta fsattr_sz(&dst) = sym_op->cipher.data.length;
136*492a19a0SVikas Gupta
137*492a19a0SVikas Gupta fsattr_va(&src) = rte_pktmbuf_mtod_offset
138*492a19a0SVikas Gupta (mbuf_src,
139*492a19a0SVikas Gupta uint8_t *,
140*492a19a0SVikas Gupta sym_op->cipher.data.offset);
141*492a19a0SVikas Gupta
142*492a19a0SVikas Gupta fsattr_va(&dst) = rte_pktmbuf_mtod_offset
143*492a19a0SVikas Gupta (mbuf_dst,
144*492a19a0SVikas Gupta uint8_t *,
145*492a19a0SVikas Gupta sym_op->cipher.data.offset);
146*492a19a0SVikas Gupta
147*492a19a0SVikas Gupta fsattr_pa(&src) = rte_pktmbuf_iova_offset(mbuf_src,
148*492a19a0SVikas Gupta sym_op->cipher.data.offset);
149*492a19a0SVikas Gupta fsattr_pa(&dst) = rte_pktmbuf_iova_offset(mbuf_dst,
150*492a19a0SVikas Gupta sym_op->cipher.data.offset);
151*492a19a0SVikas Gupta
152*492a19a0SVikas Gupta fsattr_va(&iv) = rte_crypto_op_ctod_offset(op,
153*492a19a0SVikas Gupta uint8_t *,
154*492a19a0SVikas Gupta sess->cipher.iv.offset);
155*492a19a0SVikas Gupta
156*492a19a0SVikas Gupta fsattr_pa(&iv) = 0;
157*492a19a0SVikas Gupta fsattr_sz(&iv) = sess->cipher.iv.length;
158*492a19a0SVikas Gupta
159*492a19a0SVikas Gupta fsattr_va(&cipher_key) = sess->cipher.key.data;
160*492a19a0SVikas Gupta fsattr_pa(&cipher_key) = 0;
161*492a19a0SVikas Gupta fsattr_sz(&cipher_key) = sess->cipher.key.length;
162*492a19a0SVikas Gupta
163*492a19a0SVikas Gupta fsattr_va(&auth_key) = sess->auth.key.data;
164*492a19a0SVikas Gupta fsattr_pa(&auth_key) = 0;
165*492a19a0SVikas Gupta fsattr_sz(&auth_key) = sess->auth.key.length;
166*492a19a0SVikas Gupta
167*492a19a0SVikas Gupta fsattr_va(&mac) = op->sym->auth.digest.data;
168*492a19a0SVikas Gupta fsattr_pa(&mac) = op->sym->auth.digest.phys_addr;
169*492a19a0SVikas Gupta fsattr_sz(&mac) = sess->auth.digest_length;
170*492a19a0SVikas Gupta
171*492a19a0SVikas Gupta aad_size = sym_op->auth.data.length - sym_op->cipher.data.length;
172*492a19a0SVikas Gupta
173*492a19a0SVikas Gupta if (aad_size > 0) {
174*492a19a0SVikas Gupta fsattr_sz(&aad) = aad_size;
175*492a19a0SVikas Gupta fsattr_va(&aad) = rte_pktmbuf_mtod_offset
176*492a19a0SVikas Gupta (mbuf_src,
177*492a19a0SVikas Gupta uint8_t *,
178*492a19a0SVikas Gupta sym_op->auth.data.offset);
179*492a19a0SVikas Gupta fsattr_pa(&aad) = rte_pktmbuf_iova_offset(mbuf_src,
180*492a19a0SVikas Gupta sym_op->auth.data.offset);
181*492a19a0SVikas Gupta }
182*492a19a0SVikas Gupta
183*492a19a0SVikas Gupta rc = bcmfs_crypto_build_chain_request(req, sess->cipher.algo,
184*492a19a0SVikas Gupta sess->cipher.op,
185*492a19a0SVikas Gupta sess->auth.algo,
186*492a19a0SVikas Gupta sess->auth.op,
187*492a19a0SVikas Gupta &src, &dst, &cipher_key,
188*492a19a0SVikas Gupta &auth_key, &iv,
189*492a19a0SVikas Gupta (aad_size > 0) ? (&aad) : NULL,
190*492a19a0SVikas Gupta &mac, sess->cipher_first);
191*492a19a0SVikas Gupta
192*492a19a0SVikas Gupta if (rc)
193*492a19a0SVikas Gupta op->status = RTE_CRYPTO_OP_STATUS_ERROR;
194*492a19a0SVikas Gupta
195*492a19a0SVikas Gupta return rc;
196*492a19a0SVikas Gupta }
197*492a19a0SVikas Gupta
198*492a19a0SVikas Gupta /** Process AEAD operation */
199*492a19a0SVikas Gupta static int
process_crypto_aead_op(struct rte_crypto_op * op,struct rte_mbuf * mbuf_src,struct rte_mbuf * mbuf_dst,struct bcmfs_sym_session * sess,struct bcmfs_sym_request * req)200*492a19a0SVikas Gupta process_crypto_aead_op(struct rte_crypto_op *op,
201*492a19a0SVikas Gupta struct rte_mbuf *mbuf_src,
202*492a19a0SVikas Gupta struct rte_mbuf *mbuf_dst,
203*492a19a0SVikas Gupta struct bcmfs_sym_session *sess,
204*492a19a0SVikas Gupta struct bcmfs_sym_request *req)
205*492a19a0SVikas Gupta {
206*492a19a0SVikas Gupta int rc = 0;
207*492a19a0SVikas Gupta struct fsattr src, dst, iv;
208*492a19a0SVikas Gupta struct rte_crypto_sym_op *sym_op = op->sym;
209*492a19a0SVikas Gupta struct fsattr key, aad, mac;
210*492a19a0SVikas Gupta
211*492a19a0SVikas Gupta fsattr_sz(&src) = sym_op->aead.data.length;
212*492a19a0SVikas Gupta fsattr_sz(&dst) = sym_op->aead.data.length;
213*492a19a0SVikas Gupta
214*492a19a0SVikas Gupta fsattr_va(&src) = rte_pktmbuf_mtod_offset(mbuf_src,
215*492a19a0SVikas Gupta uint8_t *,
216*492a19a0SVikas Gupta sym_op->aead.data.offset);
217*492a19a0SVikas Gupta
218*492a19a0SVikas Gupta fsattr_va(&dst) = rte_pktmbuf_mtod_offset(mbuf_dst,
219*492a19a0SVikas Gupta uint8_t *,
220*492a19a0SVikas Gupta sym_op->aead.data.offset);
221*492a19a0SVikas Gupta
222*492a19a0SVikas Gupta fsattr_pa(&src) = rte_pktmbuf_iova_offset(mbuf_src,
223*492a19a0SVikas Gupta sym_op->aead.data.offset);
224*492a19a0SVikas Gupta fsattr_pa(&dst) = rte_pktmbuf_iova_offset(mbuf_dst,
225*492a19a0SVikas Gupta sym_op->aead.data.offset);
226*492a19a0SVikas Gupta
227*492a19a0SVikas Gupta fsattr_va(&iv) = rte_crypto_op_ctod_offset(op,
228*492a19a0SVikas Gupta uint8_t *,
229*492a19a0SVikas Gupta sess->aead.iv.offset);
230*492a19a0SVikas Gupta
231*492a19a0SVikas Gupta fsattr_pa(&iv) = 0;
232*492a19a0SVikas Gupta fsattr_sz(&iv) = sess->aead.iv.length;
233*492a19a0SVikas Gupta
234*492a19a0SVikas Gupta fsattr_va(&key) = sess->aead.key.data;
235*492a19a0SVikas Gupta fsattr_pa(&key) = 0;
236*492a19a0SVikas Gupta fsattr_sz(&key) = sess->aead.key.length;
237*492a19a0SVikas Gupta
238*492a19a0SVikas Gupta fsattr_va(&mac) = op->sym->aead.digest.data;
239*492a19a0SVikas Gupta fsattr_pa(&mac) = op->sym->aead.digest.phys_addr;
240*492a19a0SVikas Gupta fsattr_sz(&mac) = sess->aead.digest_length;
241*492a19a0SVikas Gupta
242*492a19a0SVikas Gupta fsattr_va(&aad) = op->sym->aead.aad.data;
243*492a19a0SVikas Gupta fsattr_pa(&aad) = op->sym->aead.aad.phys_addr;
244*492a19a0SVikas Gupta fsattr_sz(&aad) = sess->aead.aad_length;
245*492a19a0SVikas Gupta
246*492a19a0SVikas Gupta rc = bcmfs_crypto_build_aead_request(req, sess->aead.algo,
247*492a19a0SVikas Gupta sess->aead.op, &src, &dst,
248*492a19a0SVikas Gupta &key, &iv, &aad, &mac);
249*492a19a0SVikas Gupta
250*492a19a0SVikas Gupta if (rc)
251*492a19a0SVikas Gupta op->status = RTE_CRYPTO_OP_STATUS_ERROR;
252*492a19a0SVikas Gupta
253*492a19a0SVikas Gupta return rc;
254*492a19a0SVikas Gupta }
255*492a19a0SVikas Gupta
256*492a19a0SVikas Gupta /** Process crypto operation for mbuf */
257*492a19a0SVikas Gupta int
bcmfs_process_sym_crypto_op(struct rte_crypto_op * op,struct bcmfs_sym_session * sess,struct bcmfs_sym_request * req)258*492a19a0SVikas Gupta bcmfs_process_sym_crypto_op(struct rte_crypto_op *op,
259*492a19a0SVikas Gupta struct bcmfs_sym_session *sess,
260*492a19a0SVikas Gupta struct bcmfs_sym_request *req)
261*492a19a0SVikas Gupta {
262*492a19a0SVikas Gupta struct rte_mbuf *msrc, *mdst;
263*492a19a0SVikas Gupta int rc = 0;
264*492a19a0SVikas Gupta
265*492a19a0SVikas Gupta msrc = op->sym->m_src;
266*492a19a0SVikas Gupta mdst = op->sym->m_dst ? op->sym->m_dst : op->sym->m_src;
267*492a19a0SVikas Gupta op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
268*492a19a0SVikas Gupta
269*492a19a0SVikas Gupta switch (sess->chain_order) {
270*492a19a0SVikas Gupta case BCMFS_SYM_CHAIN_ONLY_CIPHER:
271*492a19a0SVikas Gupta rc = process_crypto_cipher_op(op, msrc, mdst, sess, req);
272*492a19a0SVikas Gupta break;
273*492a19a0SVikas Gupta case BCMFS_SYM_CHAIN_ONLY_AUTH:
274*492a19a0SVikas Gupta rc = process_crypto_auth_op(op, msrc, sess, req);
275*492a19a0SVikas Gupta break;
276*492a19a0SVikas Gupta case BCMFS_SYM_CHAIN_CIPHER_AUTH:
277*492a19a0SVikas Gupta case BCMFS_SYM_CHAIN_AUTH_CIPHER:
278*492a19a0SVikas Gupta rc = process_crypto_combined_op(op, msrc, mdst, sess, req);
279*492a19a0SVikas Gupta break;
280*492a19a0SVikas Gupta case BCMFS_SYM_CHAIN_AEAD:
281*492a19a0SVikas Gupta rc = process_crypto_aead_op(op, msrc, mdst, sess, req);
282*492a19a0SVikas Gupta break;
283*492a19a0SVikas Gupta default:
284*492a19a0SVikas Gupta op->status = RTE_CRYPTO_OP_STATUS_ERROR;
285*492a19a0SVikas Gupta break;
286*492a19a0SVikas Gupta }
287*492a19a0SVikas Gupta
288*492a19a0SVikas Gupta return rc;
289*492a19a0SVikas Gupta }
290