Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2024 Marvell.
3 : : */
4 : :
5 : : #include <rte_crypto_sym.h>
6 : : #include <rte_cryptodev.h>
7 : : #include <rte_security.h>
8 : :
9 : : #include <cryptodev_pmd.h>
10 : :
11 : : #include "roc_cpt.h"
12 : : #include "roc_se.h"
13 : :
14 : : #include "cn10k_cryptodev_sec.h"
15 : : #include "cn10k_tls.h"
16 : : #include "cnxk_cryptodev.h"
17 : : #include "cnxk_cryptodev_ops.h"
18 : : #include "cnxk_security.h"
19 : :
20 : : static int
21 : 0 : tls_xform_cipher_auth_verify(struct rte_crypto_sym_xform *cipher_xform,
22 : : struct rte_crypto_sym_xform *auth_xform)
23 : : {
24 : 0 : enum rte_crypto_cipher_algorithm c_algo = cipher_xform->cipher.algo;
25 : 0 : enum rte_crypto_auth_algorithm a_algo = auth_xform->auth.algo;
26 : : int ret = -ENOTSUP;
27 : :
28 [ # # # # ]: 0 : switch (c_algo) {
29 : 0 : case RTE_CRYPTO_CIPHER_NULL:
30 [ # # # # ]: 0 : if ((a_algo == RTE_CRYPTO_AUTH_MD5_HMAC) || (a_algo == RTE_CRYPTO_AUTH_SHA1_HMAC) ||
31 : : (a_algo == RTE_CRYPTO_AUTH_SHA256_HMAC))
32 : : ret = 0;
33 : : break;
34 : 0 : case RTE_CRYPTO_CIPHER_3DES_CBC:
35 [ # # ]: 0 : if (a_algo == RTE_CRYPTO_AUTH_SHA1_HMAC)
36 : : ret = 0;
37 : : break;
38 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
39 : 0 : if ((a_algo == RTE_CRYPTO_AUTH_SHA1_HMAC) ||
40 [ # # ]: 0 : (a_algo == RTE_CRYPTO_AUTH_SHA256_HMAC))
41 : : ret = 0;
42 : : break;
43 : : default:
44 : : break;
45 : : }
46 : :
47 : 0 : return ret;
48 : : }
49 : :
50 : : static int
51 : 0 : tls_xform_cipher_verify(struct rte_crypto_sym_xform *crypto_xform)
52 : : {
53 : 0 : enum rte_crypto_cipher_algorithm c_algo = crypto_xform->cipher.algo;
54 : 0 : uint16_t keylen = crypto_xform->cipher.key.length;
55 : :
56 [ # # ]: 0 : if (((c_algo == RTE_CRYPTO_CIPHER_NULL) && (keylen == 0)) ||
57 [ # # # # ]: 0 : ((c_algo == RTE_CRYPTO_CIPHER_3DES_CBC) && (keylen == 24)) ||
58 [ # # ]: 0 : ((c_algo == RTE_CRYPTO_CIPHER_AES_CBC) && ((keylen == 16) || (keylen == 32))))
59 : 0 : return 0;
60 : :
61 : : return -EINVAL;
62 : : }
63 : :
64 : : static int
65 : : tls_xform_auth_verify(struct rte_crypto_sym_xform *crypto_xform)
66 : : {
67 : 0 : enum rte_crypto_auth_algorithm a_algo = crypto_xform->auth.algo;
68 : 0 : uint16_t keylen = crypto_xform->auth.key.length;
69 : :
70 [ # # ]: 0 : if (((a_algo == RTE_CRYPTO_AUTH_MD5_HMAC) && (keylen == 16)) ||
71 [ # # ]: 0 : ((a_algo == RTE_CRYPTO_AUTH_SHA1_HMAC) && (keylen == 20)) ||
72 [ # # ]: 0 : ((a_algo == RTE_CRYPTO_AUTH_SHA256_HMAC) && (keylen == 32)))
73 : 0 : return 0;
74 : :
75 : : return -EINVAL;
76 : : }
77 : :
78 : : static int
79 : : tls_xform_aead_verify(struct rte_security_tls_record_xform *tls_xform,
80 : : struct rte_crypto_sym_xform *crypto_xform)
81 : : {
82 : 0 : uint16_t keylen = crypto_xform->aead.key.length;
83 : :
84 [ # # ]: 0 : if (tls_xform->type == RTE_SECURITY_TLS_SESS_TYPE_WRITE &&
85 [ # # ]: 0 : crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
86 : : return -EINVAL;
87 : :
88 [ # # ]: 0 : if (tls_xform->type == RTE_SECURITY_TLS_SESS_TYPE_READ &&
89 [ # # ]: 0 : crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
90 : : return -EINVAL;
91 : :
92 [ # # ]: 0 : if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
93 [ # # ]: 0 : if ((keylen == 16) || (keylen == 32))
94 : 0 : return 0;
95 : : }
96 : :
97 : : return -EINVAL;
98 : : }
99 : :
100 : : static int
101 : 0 : cnxk_tls_xform_verify(struct rte_security_tls_record_xform *tls_xform,
102 : : struct rte_crypto_sym_xform *crypto_xform)
103 : : {
104 : : struct rte_crypto_sym_xform *auth_xform, *cipher_xform = NULL;
105 : : int ret = 0;
106 : :
107 [ # # ]: 0 : if ((tls_xform->ver != RTE_SECURITY_VERSION_TLS_1_2) &&
108 [ # # ]: 0 : (tls_xform->ver != RTE_SECURITY_VERSION_DTLS_1_2) &&
109 : : (tls_xform->ver != RTE_SECURITY_VERSION_TLS_1_3))
110 : : return -EINVAL;
111 : :
112 [ # # ]: 0 : if ((tls_xform->type != RTE_SECURITY_TLS_SESS_TYPE_READ) &&
113 : : (tls_xform->type != RTE_SECURITY_TLS_SESS_TYPE_WRITE))
114 : : return -EINVAL;
115 : :
116 [ # # ]: 0 : if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
117 : 0 : return tls_xform_aead_verify(tls_xform, crypto_xform);
118 : :
119 : : /* TLS-1.3 only support AEAD.
120 : : * Control should not reach here for TLS-1.3
121 : : */
122 [ # # ]: 0 : if (tls_xform->ver == RTE_SECURITY_VERSION_TLS_1_3)
123 : : return -EINVAL;
124 : :
125 [ # # ]: 0 : if (tls_xform->type == RTE_SECURITY_TLS_SESS_TYPE_WRITE) {
126 : : /* Egress */
127 : :
128 : : /* First should be for auth in Egress */
129 [ # # ]: 0 : if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH)
130 : : return -EINVAL;
131 : :
132 : : /* Next if present, should be for cipher in Egress */
133 [ # # ]: 0 : if ((crypto_xform->next != NULL) &&
134 [ # # ]: 0 : (crypto_xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER))
135 : : return -EINVAL;
136 : :
137 : : auth_xform = crypto_xform;
138 : : cipher_xform = crypto_xform->next;
139 : : } else {
140 : : /* Ingress */
141 : :
142 : : /* First can be for auth only when next is NULL in Ingress. */
143 [ # # ]: 0 : if ((crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) &&
144 [ # # ]: 0 : (crypto_xform->next != NULL))
145 : : return -EINVAL;
146 [ # # ]: 0 : else if ((crypto_xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER) ||
147 [ # # ]: 0 : (crypto_xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH))
148 : : return -EINVAL;
149 : :
150 : : cipher_xform = crypto_xform;
151 : : auth_xform = crypto_xform->next;
152 : : }
153 : :
154 [ # # ]: 0 : if (cipher_xform) {
155 [ # # ]: 0 : if ((tls_xform->type == RTE_SECURITY_TLS_SESS_TYPE_WRITE) &&
156 [ # # ]: 0 : !(cipher_xform->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT &&
157 [ # # ]: 0 : auth_xform->auth.op == RTE_CRYPTO_AUTH_OP_GENERATE))
158 : : return -EINVAL;
159 : :
160 [ # # ]: 0 : if ((tls_xform->type == RTE_SECURITY_TLS_SESS_TYPE_READ) &&
161 [ # # ]: 0 : !(cipher_xform->cipher.op == RTE_CRYPTO_CIPHER_OP_DECRYPT &&
162 [ # # ]: 0 : auth_xform->auth.op == RTE_CRYPTO_AUTH_OP_VERIFY))
163 : : return -EINVAL;
164 : : } else {
165 [ # # ]: 0 : if ((tls_xform->type == RTE_SECURITY_TLS_SESS_TYPE_WRITE) &&
166 [ # # ]: 0 : (auth_xform->auth.op != RTE_CRYPTO_AUTH_OP_GENERATE))
167 : : return -EINVAL;
168 : :
169 [ # # ]: 0 : if ((tls_xform->type == RTE_SECURITY_TLS_SESS_TYPE_READ) &&
170 [ # # ]: 0 : (auth_xform->auth.op == RTE_CRYPTO_AUTH_OP_VERIFY))
171 : : return -EINVAL;
172 : : }
173 : :
174 [ # # ]: 0 : if (cipher_xform)
175 : 0 : ret = tls_xform_cipher_verify(cipher_xform);
176 : :
177 [ # # ]: 0 : if (!ret)
178 : : ret = tls_xform_auth_verify(auth_xform);
179 : :
180 [ # # ]: 0 : if (cipher_xform && !ret)
181 : 0 : return tls_xform_cipher_auth_verify(cipher_xform, auth_xform);
182 : :
183 : : return ret;
184 : : }
185 : :
186 : : static int
187 : 0 : tls_write_rlens_get(struct rte_security_tls_record_xform *tls_xfrm,
188 : : struct rte_crypto_sym_xform *crypto_xfrm)
189 : : {
190 : : enum rte_crypto_cipher_algorithm c_algo = RTE_CRYPTO_CIPHER_NULL;
191 : : enum rte_crypto_auth_algorithm a_algo = RTE_CRYPTO_AUTH_NULL;
192 : : uint8_t roundup_byte, tls_hdr_len;
193 : : uint8_t mac_len, iv_len;
194 : :
195 [ # # # ]: 0 : switch (tls_xfrm->ver) {
196 : : case RTE_SECURITY_VERSION_TLS_1_2:
197 : : case RTE_SECURITY_VERSION_TLS_1_3:
198 : : tls_hdr_len = 5;
199 : : break;
200 : 0 : case RTE_SECURITY_VERSION_DTLS_1_2:
201 : : tls_hdr_len = 13;
202 : 0 : break;
203 : 0 : default:
204 : : tls_hdr_len = 0;
205 : 0 : break;
206 : : }
207 : :
208 : : /* Get Cipher and Auth algo */
209 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD)
210 : 0 : return tls_hdr_len + ROC_CPT_AES_GCM_IV_LEN + ROC_CPT_AES_GCM_MAC_LEN;
211 : :
212 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
213 : 0 : c_algo = crypto_xfrm->cipher.algo;
214 [ # # ]: 0 : if (crypto_xfrm->next)
215 : 0 : a_algo = crypto_xfrm->next->auth.algo;
216 : : } else {
217 : 0 : a_algo = crypto_xfrm->auth.algo;
218 [ # # ]: 0 : if (crypto_xfrm->next)
219 : 0 : c_algo = crypto_xfrm->next->cipher.algo;
220 : : }
221 : :
222 [ # # # # ]: 0 : switch (c_algo) {
223 : : case RTE_CRYPTO_CIPHER_NULL:
224 : : roundup_byte = 4;
225 : : iv_len = 0;
226 : : break;
227 : 0 : case RTE_CRYPTO_CIPHER_3DES_CBC:
228 : : roundup_byte = ROC_CPT_DES_BLOCK_LENGTH;
229 : : iv_len = ROC_CPT_DES_IV_LEN;
230 : 0 : break;
231 : 0 : case RTE_CRYPTO_CIPHER_AES_CBC:
232 : : roundup_byte = ROC_CPT_AES_BLOCK_LENGTH;
233 : : iv_len = ROC_CPT_AES_CBC_IV_LEN;
234 : 0 : break;
235 : 0 : default:
236 : : roundup_byte = 0;
237 : : iv_len = 0;
238 : 0 : break;
239 : : }
240 : :
241 : : switch (a_algo) {
242 : : case RTE_CRYPTO_AUTH_NULL:
243 : : mac_len = 0;
244 : : break;
245 : : case RTE_CRYPTO_AUTH_MD5_HMAC:
246 : : mac_len = 16;
247 : : break;
248 : : case RTE_CRYPTO_AUTH_SHA1_HMAC:
249 : : mac_len = 20;
250 : : break;
251 : : case RTE_CRYPTO_AUTH_SHA256_HMAC:
252 : : mac_len = 32;
253 : : break;
254 : : default:
255 : : mac_len = 0;
256 : : break;
257 : : }
258 : :
259 : 0 : return tls_hdr_len + iv_len + mac_len + roundup_byte;
260 : : }
261 : :
262 : : static void
263 : : tls_write_sa_init(struct roc_ie_ot_tls_write_sa *sa)
264 : : {
265 : : size_t offset;
266 : :
267 : : memset(sa, 0, sizeof(struct roc_ie_ot_tls_write_sa));
268 : :
269 : : offset = offsetof(struct roc_ie_ot_tls_write_sa, tls_12.w26_rsvd7);
270 : 0 : sa->w0.s.hw_ctx_off = offset / ROC_CTX_UNIT_8B;
271 : 0 : sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off;
272 : 0 : sa->w0.s.ctx_size = ROC_IE_OT_TLS_CTX_ILEN;
273 : 0 : sa->w0.s.ctx_hdr_size = ROC_IE_OT_TLS_CTX_HDR_SIZE;
274 : 0 : sa->w0.s.aop_valid = 1;
275 : : }
276 : :
277 : : static void
278 : : tls_read_sa_init(struct roc_ie_ot_tls_read_sa *sa)
279 : : {
280 : : size_t offset;
281 : :
282 : : memset(sa, 0, sizeof(struct roc_ie_ot_tls_read_sa));
283 : :
284 : : offset = offsetof(struct roc_ie_ot_tls_read_sa, tls_12.ctx);
285 : 0 : sa->w0.s.hw_ctx_off = offset / ROC_CTX_UNIT_8B;
286 : 0 : sa->w0.s.ctx_push_size = sa->w0.s.hw_ctx_off;
287 : 0 : sa->w0.s.ctx_size = ROC_IE_OT_TLS_CTX_ILEN;
288 : 0 : sa->w0.s.ctx_hdr_size = ROC_IE_OT_TLS_CTX_HDR_SIZE;
289 : 0 : sa->w0.s.aop_valid = 1;
290 : : }
291 : :
292 : : static size_t
293 : : tls_read_ctx_size(struct roc_ie_ot_tls_read_sa *sa, enum rte_security_tls_version tls_ver)
294 : : {
295 : : size_t size;
296 : :
297 : : /* Variable based on Anti-replay Window */
298 [ # # ]: 0 : if (tls_ver == RTE_SECURITY_VERSION_TLS_1_3) {
299 : : size = offsetof(struct roc_ie_ot_tls_read_sa, tls_13.ctx) +
300 : : offsetof(struct roc_ie_ot_tls_read_ctx_update_reg, ar_winbits);
301 : : } else {
302 : : size = offsetof(struct roc_ie_ot_tls_read_sa, tls_12.ctx) +
303 : : offsetof(struct roc_ie_ot_tls_read_ctx_update_reg, ar_winbits);
304 : : }
305 : :
306 [ # # ]: 0 : if (sa->w0.s.ar_win)
307 : 0 : size += (1 << (sa->w0.s.ar_win - 1)) * sizeof(uint64_t);
308 : :
309 : : return size;
310 : : }
311 : :
312 : : static int
313 : 0 : tls_read_sa_fill(struct roc_ie_ot_tls_read_sa *read_sa,
314 : : struct rte_security_tls_record_xform *tls_xfrm,
315 : : struct rte_crypto_sym_xform *crypto_xfrm)
316 : : {
317 [ # # ]: 0 : enum rte_security_tls_version tls_ver = tls_xfrm->ver;
318 : : struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm;
319 : : const uint8_t *key = NULL;
320 : : uint64_t *tmp, *tmp_key;
321 : : uint32_t replay_win_sz;
322 : : uint8_t *cipher_key;
323 : : int i, length = 0;
324 : : size_t offset;
325 : :
326 : : /* Initialize the SA */
327 : : memset(read_sa, 0, sizeof(struct roc_ie_ot_tls_read_sa));
328 : :
329 [ # # ]: 0 : if (tls_ver == RTE_SECURITY_VERSION_TLS_1_2) {
330 : 0 : read_sa->w2.s.version_select = ROC_IE_OT_TLS_VERSION_TLS_12;
331 : 0 : read_sa->tls_12.ctx.ar_valid_mask = tls_xfrm->tls_1_2.seq_no - 1;
332 [ # # ]: 0 : } else if (tls_ver == RTE_SECURITY_VERSION_DTLS_1_2) {
333 : 0 : read_sa->w2.s.version_select = ROC_IE_OT_TLS_VERSION_DTLS_12;
334 [ # # ]: 0 : } else if (tls_ver == RTE_SECURITY_VERSION_TLS_1_3) {
335 : 0 : read_sa->w2.s.version_select = ROC_IE_OT_TLS_VERSION_TLS_13;
336 : 0 : read_sa->tls_13.ctx.ar_valid_mask = tls_xfrm->tls_1_3.seq_no - 1;
337 : : }
338 : :
339 : 0 : cipher_key = read_sa->cipher_key;
340 : :
341 : : /* Set encryption algorithm */
342 [ # # ]: 0 : if ((crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) &&
343 [ # # ]: 0 : (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_AES_GCM)) {
344 : 0 : read_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_AES_GCM;
345 : :
346 : 0 : length = crypto_xfrm->aead.key.length;
347 [ # # ]: 0 : if (length == 16)
348 : 0 : read_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_128;
349 : : else
350 : 0 : read_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_256;
351 : :
352 : 0 : key = crypto_xfrm->aead.key.data;
353 [ # # ]: 0 : memcpy(cipher_key, key, length);
354 : :
355 [ # # ]: 0 : if (tls_ver == RTE_SECURITY_VERSION_TLS_1_2)
356 : 0 : memcpy(((uint8_t *)cipher_key + 32), &tls_xfrm->tls_1_2.imp_nonce, 4);
357 [ # # ]: 0 : else if (tls_ver == RTE_SECURITY_VERSION_DTLS_1_2)
358 : 0 : memcpy(((uint8_t *)cipher_key + 32), &tls_xfrm->dtls_1_2.imp_nonce, 4);
359 [ # # ]: 0 : else if (tls_ver == RTE_SECURITY_VERSION_TLS_1_3)
360 : 0 : memcpy(((uint8_t *)cipher_key + 32), &tls_xfrm->tls_1_3.imp_nonce, 12);
361 : :
362 : 0 : goto key_swap;
363 : : }
364 : :
365 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
366 : : auth_xfrm = crypto_xfrm;
367 : 0 : cipher_xfrm = crypto_xfrm->next;
368 : : } else {
369 : : cipher_xfrm = crypto_xfrm;
370 : 0 : auth_xfrm = crypto_xfrm->next;
371 : : }
372 : :
373 [ # # ]: 0 : if (cipher_xfrm != NULL) {
374 [ # # ]: 0 : if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
375 : 0 : read_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_3DES;
376 : 0 : length = cipher_xfrm->cipher.key.length;
377 [ # # ]: 0 : } else if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
378 : 0 : read_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_AES_CBC;
379 : 0 : length = cipher_xfrm->cipher.key.length;
380 [ # # ]: 0 : if (length == 16)
381 : 0 : read_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_128;
382 [ # # ]: 0 : else if (length == 32)
383 : 0 : read_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_256;
384 : : else
385 : : return -EINVAL;
386 : : } else {
387 : : return -EINVAL;
388 : : }
389 : :
390 : 0 : key = cipher_xfrm->cipher.key.data;
391 : 0 : memcpy(cipher_key, key, length);
392 : : }
393 : :
394 [ # # ]: 0 : if (auth_xfrm->auth.algo == RTE_CRYPTO_AUTH_MD5_HMAC)
395 : 0 : read_sa->w2.s.mac_select = ROC_IE_OT_TLS_MAC_MD5;
396 [ # # ]: 0 : else if (auth_xfrm->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC)
397 : 0 : read_sa->w2.s.mac_select = ROC_IE_OT_TLS_MAC_SHA1;
398 [ # # ]: 0 : else if (auth_xfrm->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC)
399 : 0 : read_sa->w2.s.mac_select = ROC_IE_OT_TLS_MAC_SHA2_256;
400 : : else
401 : : return -EINVAL;
402 : :
403 : 0 : roc_se_hmac_opad_ipad_gen(read_sa->w2.s.mac_select, auth_xfrm->auth.key.data,
404 : 0 : auth_xfrm->auth.key.length, read_sa->tls_12.opad_ipad,
405 : : ROC_SE_TLS);
406 : :
407 : : tmp = (uint64_t *)read_sa->tls_12.opad_ipad;
408 [ # # ]: 0 : for (i = 0; i < (int)(ROC_CTX_MAX_OPAD_IPAD_LEN / sizeof(uint64_t)); i++)
409 [ # # ]: 0 : tmp[i] = rte_be_to_cpu_64(tmp[i]);
410 : :
411 : 0 : key_swap:
412 : : tmp_key = (uint64_t *)cipher_key;
413 [ # # ]: 0 : for (i = 0; i < (int)(ROC_IE_OT_TLS_CTX_MAX_KEY_IV_LEN / sizeof(uint64_t)); i++)
414 [ # # ]: 0 : tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
415 : :
416 [ # # ]: 0 : if (tls_xfrm->ver == RTE_SECURITY_VERSION_DTLS_1_2) {
417 : : /* Only support power-of-two window sizes supported */
418 : 0 : replay_win_sz = tls_xfrm->dtls_1_2.ar_win_sz;
419 [ # # ]: 0 : if (replay_win_sz) {
420 [ # # ]: 0 : if (!rte_is_power_of_2(replay_win_sz) ||
421 : : replay_win_sz > ROC_IE_OT_TLS_AR_WIN_SIZE_MAX)
422 : : return -ENOTSUP;
423 : :
424 : 0 : read_sa->w0.s.ar_win = rte_log2_u32(replay_win_sz) - 5;
425 : : }
426 : : }
427 : :
428 : 0 : read_sa->w0.s.ctx_hdr_size = ROC_IE_OT_TLS_CTX_HDR_SIZE;
429 : 0 : read_sa->w0.s.aop_valid = 1;
430 : :
431 : : offset = offsetof(struct roc_ie_ot_tls_read_sa, tls_12.ctx);
432 [ # # ]: 0 : if (tls_ver == RTE_SECURITY_VERSION_TLS_1_3)
433 : : offset = offsetof(struct roc_ie_ot_tls_read_sa, tls_13.ctx);
434 : :
435 : : /* Entire context size in 128B units */
436 : 0 : read_sa->w0.s.ctx_size =
437 : 0 : (PLT_ALIGN_CEIL(tls_read_ctx_size(read_sa, tls_ver), ROC_CTX_UNIT_128B) /
438 : 0 : ROC_CTX_UNIT_128B) -
439 : : 1;
440 : :
441 : : /* Word offset for HW managed CTX field */
442 : 0 : read_sa->w0.s.hw_ctx_off = offset / 8;
443 : 0 : read_sa->w0.s.ctx_push_size = read_sa->w0.s.hw_ctx_off;
444 : :
445 : : rte_wmb();
446 : :
447 : 0 : return 0;
448 : : }
449 : :
450 : : static int
451 : 0 : tls_write_sa_fill(struct roc_ie_ot_tls_write_sa *write_sa,
452 : : struct rte_security_tls_record_xform *tls_xfrm,
453 : : struct rte_crypto_sym_xform *crypto_xfrm)
454 : : {
455 : 0 : enum rte_security_tls_version tls_ver = tls_xfrm->ver;
456 : : struct rte_crypto_sym_xform *auth_xfrm, *cipher_xfrm;
457 : : const uint8_t *key = NULL;
458 : : uint8_t *cipher_key;
459 : : uint64_t *tmp_key;
460 : : int i, length = 0;
461 : : size_t offset;
462 : :
463 [ # # ]: 0 : if (tls_ver == RTE_SECURITY_VERSION_TLS_1_2) {
464 : 0 : write_sa->w2.s.version_select = ROC_IE_OT_TLS_VERSION_TLS_12;
465 : 0 : write_sa->tls_12.seq_num = tls_xfrm->tls_1_2.seq_no - 1;
466 [ # # ]: 0 : } else if (tls_ver == RTE_SECURITY_VERSION_DTLS_1_2) {
467 : 0 : write_sa->w2.s.version_select = ROC_IE_OT_TLS_VERSION_DTLS_12;
468 : 0 : write_sa->tls_12.seq_num = ((uint64_t)tls_xfrm->dtls_1_2.epoch << 48) |
469 : 0 : (tls_xfrm->dtls_1_2.seq_no & 0x0000ffffffffffff);
470 : 0 : write_sa->tls_12.seq_num -= 1;
471 [ # # ]: 0 : } else if (tls_ver == RTE_SECURITY_VERSION_TLS_1_3) {
472 : 0 : write_sa->w2.s.version_select = ROC_IE_OT_TLS_VERSION_TLS_13;
473 : 0 : write_sa->tls_13.seq_num = tls_xfrm->tls_1_3.seq_no - 1;
474 : : }
475 : :
476 : 0 : cipher_key = write_sa->cipher_key;
477 : :
478 : : /* Set encryption algorithm */
479 [ # # ]: 0 : if ((crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) &&
480 [ # # ]: 0 : (crypto_xfrm->aead.algo == RTE_CRYPTO_AEAD_AES_GCM)) {
481 : 0 : write_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_AES_GCM;
482 : :
483 : 0 : length = crypto_xfrm->aead.key.length;
484 [ # # ]: 0 : if (length == 16)
485 : 0 : write_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_128;
486 : : else
487 : 0 : write_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_256;
488 : :
489 : 0 : key = crypto_xfrm->aead.key.data;
490 [ # # ]: 0 : memcpy(cipher_key, key, length);
491 : :
492 [ # # ]: 0 : if (tls_ver == RTE_SECURITY_VERSION_TLS_1_2)
493 : 0 : memcpy(((uint8_t *)cipher_key + 32), &tls_xfrm->tls_1_2.imp_nonce, 4);
494 [ # # ]: 0 : else if (tls_ver == RTE_SECURITY_VERSION_DTLS_1_2)
495 : 0 : memcpy(((uint8_t *)cipher_key + 32), &tls_xfrm->dtls_1_2.imp_nonce, 4);
496 [ # # ]: 0 : else if (tls_ver == RTE_SECURITY_VERSION_TLS_1_3)
497 : 0 : memcpy(((uint8_t *)cipher_key + 32), &tls_xfrm->tls_1_3.imp_nonce, 12);
498 : :
499 : 0 : goto key_swap;
500 : : }
501 : :
502 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
503 : : auth_xfrm = crypto_xfrm;
504 : 0 : cipher_xfrm = crypto_xfrm->next;
505 : : } else {
506 : : cipher_xfrm = crypto_xfrm;
507 : 0 : auth_xfrm = crypto_xfrm->next;
508 : : }
509 : :
510 [ # # ]: 0 : if (cipher_xfrm != NULL) {
511 [ # # ]: 0 : if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC) {
512 : 0 : write_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_3DES;
513 : 0 : length = cipher_xfrm->cipher.key.length;
514 [ # # ]: 0 : } else if (cipher_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
515 : 0 : write_sa->w2.s.cipher_select = ROC_IE_OT_TLS_CIPHER_AES_CBC;
516 : 0 : length = cipher_xfrm->cipher.key.length;
517 [ # # ]: 0 : if (length == 16)
518 : 0 : write_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_128;
519 [ # # ]: 0 : else if (length == 32)
520 : 0 : write_sa->w2.s.aes_key_len = ROC_IE_OT_TLS_AES_KEY_LEN_256;
521 : : else
522 : : return -EINVAL;
523 : : } else {
524 : : return -EINVAL;
525 : : }
526 : :
527 : 0 : key = cipher_xfrm->cipher.key.data;
528 [ # # ]: 0 : if (key != NULL && length != 0) {
529 : : /* Copy encryption key */
530 : 0 : memcpy(cipher_key, key, length);
531 : : }
532 : : }
533 : :
534 [ # # ]: 0 : if (auth_xfrm != NULL) {
535 [ # # ]: 0 : if (auth_xfrm->auth.algo == RTE_CRYPTO_AUTH_MD5_HMAC)
536 : 0 : write_sa->w2.s.mac_select = ROC_IE_OT_TLS_MAC_MD5;
537 [ # # ]: 0 : else if (auth_xfrm->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC)
538 : 0 : write_sa->w2.s.mac_select = ROC_IE_OT_TLS_MAC_SHA1;
539 [ # # ]: 0 : else if (auth_xfrm->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC)
540 : 0 : write_sa->w2.s.mac_select = ROC_IE_OT_TLS_MAC_SHA2_256;
541 : : else
542 : : return -EINVAL;
543 : :
544 : 0 : roc_se_hmac_opad_ipad_gen(write_sa->w2.s.mac_select, auth_xfrm->auth.key.data,
545 : 0 : auth_xfrm->auth.key.length, write_sa->tls_12.opad_ipad,
546 : : ROC_SE_TLS);
547 : : }
548 : :
549 : 0 : tmp_key = (uint64_t *)write_sa->tls_12.opad_ipad;
550 [ # # ]: 0 : for (i = 0; i < (int)(ROC_CTX_MAX_OPAD_IPAD_LEN / sizeof(uint64_t)); i++)
551 [ # # ]: 0 : tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
552 : :
553 : 0 : key_swap:
554 : : tmp_key = (uint64_t *)cipher_key;
555 [ # # ]: 0 : for (i = 0; i < (int)(ROC_IE_OT_TLS_CTX_MAX_KEY_IV_LEN / sizeof(uint64_t)); i++)
556 [ # # ]: 0 : tmp_key[i] = rte_be_to_cpu_64(tmp_key[i]);
557 : :
558 : 0 : write_sa->w0.s.ctx_hdr_size = ROC_IE_OT_TLS_CTX_HDR_SIZE;
559 : : /* Entire context size in 128B units */
560 : 0 : write_sa->w0.s.ctx_size =
561 : : (PLT_ALIGN_CEIL(sizeof(struct roc_ie_ot_tls_write_sa), ROC_CTX_UNIT_128B) /
562 : : ROC_CTX_UNIT_128B) -
563 : : 1;
564 : : offset = offsetof(struct roc_ie_ot_tls_write_sa, tls_12.w26_rsvd7);
565 : :
566 [ # # ]: 0 : if (tls_ver == RTE_SECURITY_VERSION_TLS_1_3) {
567 : : offset = offsetof(struct roc_ie_ot_tls_write_sa, tls_13.w10_rsvd7);
568 : 0 : write_sa->w0.s.ctx_size -= 1;
569 : : }
570 : :
571 : : /* Word offset for HW managed CTX field */
572 : 0 : write_sa->w0.s.hw_ctx_off = offset / 8;
573 : 0 : write_sa->w0.s.ctx_push_size = write_sa->w0.s.hw_ctx_off;
574 : :
575 : 0 : write_sa->w0.s.aop_valid = 1;
576 : :
577 : 0 : write_sa->w2.s.iv_at_cptr = ROC_IE_OT_TLS_IV_SRC_DEFAULT;
578 : :
579 [ # # ]: 0 : if (write_sa->w2.s.version_select != ROC_IE_OT_TLS_VERSION_TLS_13) {
580 : : #ifdef LA_IPSEC_DEBUG
581 : : if (tls_xfrm->options.iv_gen_disable == 1)
582 : : write_sa->w2.s.iv_at_cptr = ROC_IE_OT_TLS_IV_SRC_FROM_SA;
583 : : #else
584 [ # # ]: 0 : if (tls_xfrm->options.iv_gen_disable) {
585 : 0 : plt_err("Application provided IV is not supported");
586 : 0 : return -ENOTSUP;
587 : : }
588 : : #endif
589 : : }
590 : :
591 : : rte_wmb();
592 : :
593 : 0 : return 0;
594 : : }
595 : :
596 : : static int
597 : 0 : cn10k_tls_read_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
598 : : struct rte_security_tls_record_xform *tls_xfrm,
599 : : struct rte_crypto_sym_xform *crypto_xfrm,
600 : : struct cn10k_sec_session *sec_sess)
601 : : {
602 : : struct roc_ie_ot_tls_read_sa *sa_dptr;
603 : : struct cn10k_tls_record *tls;
604 : : union cpt_inst_w4 inst_w4;
605 : : void *read_sa;
606 : : int ret = 0;
607 : :
608 : : tls = &sec_sess->tls_rec;
609 : 0 : read_sa = &tls->read_sa;
610 : :
611 : : /* Allocate memory to be used as dptr for CPT ucode WRITE_SA op */
612 : 0 : sa_dptr = plt_zmalloc(sizeof(struct roc_ie_ot_tls_read_sa), 8);
613 [ # # ]: 0 : if (sa_dptr == NULL) {
614 : 0 : plt_err("Could not allocate memory for SA DPTR");
615 : 0 : return -ENOMEM;
616 : : }
617 : :
618 : : /* Translate security parameters to SA */
619 : 0 : ret = tls_read_sa_fill(sa_dptr, tls_xfrm, crypto_xfrm);
620 [ # # ]: 0 : if (ret) {
621 : 0 : plt_err("Could not fill read session parameters");
622 : 0 : goto sa_dptr_free;
623 : : }
624 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
625 : 0 : sec_sess->iv_offset = crypto_xfrm->aead.iv.offset;
626 : 0 : sec_sess->iv_length = crypto_xfrm->aead.iv.length;
627 [ # # ]: 0 : } else if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
628 : 0 : sec_sess->iv_offset = crypto_xfrm->cipher.iv.offset;
629 : 0 : sec_sess->iv_length = crypto_xfrm->cipher.iv.length;
630 : : } else {
631 : 0 : sec_sess->iv_offset = crypto_xfrm->auth.iv.offset;
632 : 0 : sec_sess->iv_length = crypto_xfrm->auth.iv.length;
633 : : }
634 : :
635 : 0 : sec_sess->proto = RTE_SECURITY_PROTOCOL_TLS_RECORD;
636 : :
637 : : /* pre-populate CPT INST word 4 */
638 : 0 : inst_w4.u64 = 0;
639 [ # # ]: 0 : if ((sa_dptr->w2.s.version_select == ROC_IE_OT_TLS_VERSION_TLS_12) ||
640 : : (sa_dptr->w2.s.version_select == ROC_IE_OT_TLS_VERSION_DTLS_12)) {
641 : 0 : inst_w4.s.opcode_major = ROC_IE_OT_TLS_MAJOR_OP_RECORD_DEC | ROC_IE_OT_INPLACE_BIT;
642 [ # # ]: 0 : } else if (sa_dptr->w2.s.version_select == ROC_IE_OT_TLS_VERSION_TLS_13) {
643 : 0 : inst_w4.s.opcode_major =
644 : : ROC_IE_OT_TLS13_MAJOR_OP_RECORD_DEC | ROC_IE_OT_INPLACE_BIT;
645 : : }
646 : :
647 : 0 : sec_sess->inst.w4 = inst_w4.u64;
648 : 0 : sec_sess->inst.w7 = cpt_inst_w7_get(roc_cpt, read_sa);
649 : :
650 : : memset(read_sa, 0, sizeof(struct roc_ie_ot_tls_read_sa));
651 : :
652 : : /* Copy word0 from sa_dptr to populate ctx_push_sz ctx_size fields */
653 : : memcpy(read_sa, sa_dptr, 8);
654 : :
655 : : rte_atomic_thread_fence(rte_memory_order_seq_cst);
656 : :
657 : : /* Write session using microcode opcode */
658 : 0 : ret = roc_cpt_ctx_write(lf, sa_dptr, read_sa, sizeof(struct roc_ie_ot_tls_read_sa));
659 [ # # ]: 0 : if (ret) {
660 : 0 : plt_err("Could not write read session to hardware");
661 : 0 : goto sa_dptr_free;
662 : : }
663 : :
664 : : /* Trigger CTX flush so that data is written back to DRAM */
665 : 0 : roc_cpt_lf_ctx_flush(lf, read_sa, true);
666 : :
667 : : rte_atomic_thread_fence(rte_memory_order_seq_cst);
668 : :
669 : 0 : sa_dptr_free:
670 : 0 : plt_free(sa_dptr);
671 : :
672 : 0 : return ret;
673 : : }
674 : :
675 : : static int
676 : 0 : cn10k_tls_write_sa_create(struct roc_cpt *roc_cpt, struct roc_cpt_lf *lf,
677 : : struct rte_security_tls_record_xform *tls_xfrm,
678 : : struct rte_crypto_sym_xform *crypto_xfrm,
679 : : struct cn10k_sec_session *sec_sess)
680 : : {
681 : : struct roc_ie_ot_tls_write_sa *sa_dptr;
682 : : struct cn10k_tls_record *tls;
683 : : union cpt_inst_w4 inst_w4;
684 : : void *write_sa;
685 : : int ret = 0;
686 : :
687 : : tls = &sec_sess->tls_rec;
688 : 0 : write_sa = &tls->write_sa;
689 : :
690 : : /* Allocate memory to be used as dptr for CPT ucode WRITE_SA op */
691 : 0 : sa_dptr = plt_zmalloc(sizeof(struct roc_ie_ot_tls_write_sa), 8);
692 [ # # ]: 0 : if (sa_dptr == NULL) {
693 : 0 : plt_err("Could not allocate memory for SA DPTR");
694 : 0 : return -ENOMEM;
695 : : }
696 : :
697 : : /* Translate security parameters to SA */
698 : 0 : ret = tls_write_sa_fill(sa_dptr, tls_xfrm, crypto_xfrm);
699 [ # # ]: 0 : if (ret) {
700 : 0 : plt_err("Could not fill write session parameters");
701 : 0 : goto sa_dptr_free;
702 : : }
703 : :
704 [ # # ]: 0 : if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
705 : 0 : sec_sess->iv_offset = crypto_xfrm->aead.iv.offset;
706 : 0 : sec_sess->iv_length = crypto_xfrm->aead.iv.length;
707 [ # # ]: 0 : } else if (crypto_xfrm->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
708 : 0 : sec_sess->iv_offset = crypto_xfrm->cipher.iv.offset;
709 : 0 : sec_sess->iv_length = crypto_xfrm->cipher.iv.length;
710 : : } else {
711 : 0 : sec_sess->iv_offset = crypto_xfrm->next->cipher.iv.offset;
712 : 0 : sec_sess->iv_length = crypto_xfrm->next->cipher.iv.length;
713 : : }
714 : :
715 : 0 : sec_sess->tls.is_write = true;
716 : 0 : sec_sess->tls.enable_padding = tls_xfrm->options.extra_padding_enable;
717 : 0 : sec_sess->max_extended_len = tls_write_rlens_get(tls_xfrm, crypto_xfrm);
718 : 0 : sec_sess->proto = RTE_SECURITY_PROTOCOL_TLS_RECORD;
719 : :
720 : : /* pre-populate CPT INST word 4 */
721 : 0 : inst_w4.u64 = 0;
722 [ # # ]: 0 : if ((sa_dptr->w2.s.version_select == ROC_IE_OT_TLS_VERSION_TLS_12) ||
723 : : (sa_dptr->w2.s.version_select == ROC_IE_OT_TLS_VERSION_DTLS_12)) {
724 : 0 : inst_w4.s.opcode_major = ROC_IE_OT_TLS_MAJOR_OP_RECORD_ENC | ROC_IE_OT_INPLACE_BIT;
725 [ # # ]: 0 : } else if (sa_dptr->w2.s.version_select == ROC_IE_OT_TLS_VERSION_TLS_13) {
726 : 0 : inst_w4.s.opcode_major =
727 : : ROC_IE_OT_TLS13_MAJOR_OP_RECORD_ENC | ROC_IE_OT_INPLACE_BIT;
728 : : }
729 : 0 : sec_sess->inst.w4 = inst_w4.u64;
730 : 0 : sec_sess->inst.w7 = cpt_inst_w7_get(roc_cpt, write_sa);
731 : :
732 : : memset(write_sa, 0, sizeof(struct roc_ie_ot_tls_write_sa));
733 : :
734 : : /* Copy word0 from sa_dptr to populate ctx_push_sz ctx_size fields */
735 : : memcpy(write_sa, sa_dptr, 8);
736 : :
737 : : rte_atomic_thread_fence(rte_memory_order_seq_cst);
738 : :
739 : : /* Write session using microcode opcode */
740 : 0 : ret = roc_cpt_ctx_write(lf, sa_dptr, write_sa, sizeof(struct roc_ie_ot_tls_write_sa));
741 [ # # ]: 0 : if (ret) {
742 : 0 : plt_err("Could not write tls write session to hardware");
743 : 0 : goto sa_dptr_free;
744 : : }
745 : :
746 : : /* Trigger CTX flush so that data is written back to DRAM */
747 : 0 : roc_cpt_lf_ctx_flush(lf, write_sa, false);
748 : :
749 : : rte_atomic_thread_fence(rte_memory_order_seq_cst);
750 : :
751 : 0 : sa_dptr_free:
752 : 0 : plt_free(sa_dptr);
753 : :
754 : 0 : return ret;
755 : : }
756 : :
757 : : int
758 : 0 : cn10k_tls_record_session_create(struct cnxk_cpt_vf *vf, struct cnxk_cpt_qp *qp,
759 : : struct rte_security_tls_record_xform *tls_xfrm,
760 : : struct rte_crypto_sym_xform *crypto_xfrm,
761 : : struct rte_security_session *sess)
762 : : {
763 : : struct roc_cpt *roc_cpt;
764 : : int ret;
765 : :
766 : 0 : ret = cnxk_tls_xform_verify(tls_xfrm, crypto_xfrm);
767 [ # # ]: 0 : if (ret)
768 : : return ret;
769 : :
770 : 0 : roc_cpt = &vf->cpt;
771 : :
772 [ # # ]: 0 : if (tls_xfrm->type == RTE_SECURITY_TLS_SESS_TYPE_READ)
773 : 0 : return cn10k_tls_read_sa_create(roc_cpt, &qp->lf, tls_xfrm, crypto_xfrm,
774 : : (struct cn10k_sec_session *)sess);
775 : : else
776 : 0 : return cn10k_tls_write_sa_create(roc_cpt, &qp->lf, tls_xfrm, crypto_xfrm,
777 : : (struct cn10k_sec_session *)sess);
778 : : }
779 : :
780 : : int
781 : 0 : cn10k_sec_tls_session_destroy(struct cnxk_cpt_qp *qp, struct cn10k_sec_session *sess)
782 : : {
783 : : struct cn10k_tls_record *tls;
784 : : struct roc_cpt_lf *lf;
785 : : void *sa_dptr = NULL;
786 : : int ret;
787 : :
788 : 0 : lf = &qp->lf;
789 : :
790 : : tls = &sess->tls_rec;
791 : :
792 : : /* Trigger CTX flush to write dirty data back to DRAM */
793 : 0 : roc_cpt_lf_ctx_flush(lf, &tls->read_sa, false);
794 : :
795 : : ret = -1;
796 : :
797 [ # # ]: 0 : if (sess->tls.is_write) {
798 : 0 : sa_dptr = plt_zmalloc(sizeof(struct roc_ie_ot_tls_write_sa), 8);
799 [ # # ]: 0 : if (sa_dptr != NULL) {
800 : : tls_write_sa_init(sa_dptr);
801 : :
802 : 0 : ret = roc_cpt_ctx_write(lf, sa_dptr, &tls->write_sa,
803 : : sizeof(struct roc_ie_ot_tls_write_sa));
804 : : }
805 : : } else {
806 : 0 : sa_dptr = plt_zmalloc(sizeof(struct roc_ie_ot_tls_read_sa), 8);
807 [ # # ]: 0 : if (sa_dptr != NULL) {
808 : : tls_read_sa_init(sa_dptr);
809 : :
810 : 0 : ret = roc_cpt_ctx_write(lf, sa_dptr, &tls->read_sa,
811 : : sizeof(struct roc_ie_ot_tls_read_sa));
812 : : }
813 : : }
814 : :
815 : 0 : plt_free(sa_dptr);
816 : :
817 [ # # ]: 0 : if (ret) {
818 : : /* MC write_ctx failed. Attempt reload of CTX */
819 : :
820 : : /* Wait for 1 ms so that flush is complete */
821 : : rte_delay_ms(1);
822 : :
823 : : rte_atomic_thread_fence(rte_memory_order_seq_cst);
824 : :
825 : : /* Trigger CTX reload to fetch new data from DRAM */
826 : 0 : roc_cpt_lf_ctx_reload(lf, &tls->read_sa);
827 : : }
828 : :
829 : 0 : return 0;
830 : : }
|