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