crypto/cnxk: add AEAD operation in session
[dpdk.git] / drivers / crypto / cnxk / cnxk_se.h
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 "roc_se.h"
10
11 struct cnxk_se_sess {
12         uint16_t cpt_op : 4;
13         uint16_t zsk_flag : 4;
14         uint16_t aes_gcm : 1;
15         uint16_t aes_ctr : 1;
16         uint16_t chacha_poly : 1;
17         uint16_t is_null : 1;
18         uint16_t is_gmac : 1;
19         uint16_t rsvd1 : 3;
20         uint16_t aad_length;
21         uint8_t mac_len;
22         uint8_t iv_length;
23         uint8_t auth_iv_length;
24         uint16_t iv_offset;
25         uint16_t auth_iv_offset;
26         uint32_t salt;
27         uint64_t cpt_inst_w7;
28         struct roc_se_ctx roc_se_ctx;
29 } __rte_cache_aligned;
30
31 static __rte_always_inline int
32 cpt_mac_len_verify(struct rte_crypto_auth_xform *auth)
33 {
34         uint16_t mac_len = auth->digest_length;
35         int ret;
36
37         switch (auth->algo) {
38         case RTE_CRYPTO_AUTH_MD5:
39         case RTE_CRYPTO_AUTH_MD5_HMAC:
40                 ret = (mac_len == 16) ? 0 : -1;
41                 break;
42         case RTE_CRYPTO_AUTH_SHA1:
43         case RTE_CRYPTO_AUTH_SHA1_HMAC:
44                 ret = (mac_len == 20) ? 0 : -1;
45                 break;
46         case RTE_CRYPTO_AUTH_SHA224:
47         case RTE_CRYPTO_AUTH_SHA224_HMAC:
48                 ret = (mac_len == 28) ? 0 : -1;
49                 break;
50         case RTE_CRYPTO_AUTH_SHA256:
51         case RTE_CRYPTO_AUTH_SHA256_HMAC:
52                 ret = (mac_len == 32) ? 0 : -1;
53                 break;
54         case RTE_CRYPTO_AUTH_SHA384:
55         case RTE_CRYPTO_AUTH_SHA384_HMAC:
56                 ret = (mac_len == 48) ? 0 : -1;
57                 break;
58         case RTE_CRYPTO_AUTH_SHA512:
59         case RTE_CRYPTO_AUTH_SHA512_HMAC:
60                 ret = (mac_len == 64) ? 0 : -1;
61                 break;
62         case RTE_CRYPTO_AUTH_NULL:
63                 ret = 0;
64                 break;
65         default:
66                 ret = -1;
67         }
68
69         return ret;
70 }
71
72 static __rte_always_inline int
73 fill_sess_aead(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
74 {
75         struct rte_crypto_aead_xform *aead_form;
76         roc_se_cipher_type enc_type = 0; /* NULL Cipher type */
77         roc_se_auth_type auth_type = 0;  /* NULL Auth type */
78         uint32_t cipher_key_len = 0;
79         uint8_t aes_gcm = 0;
80         aead_form = &xform->aead;
81
82         if (aead_form->op == RTE_CRYPTO_AEAD_OP_ENCRYPT) {
83                 sess->cpt_op |= ROC_SE_OP_CIPHER_ENCRYPT;
84                 sess->cpt_op |= ROC_SE_OP_AUTH_GENERATE;
85         } else if (aead_form->op == RTE_CRYPTO_AEAD_OP_DECRYPT) {
86                 sess->cpt_op |= ROC_SE_OP_CIPHER_DECRYPT;
87                 sess->cpt_op |= ROC_SE_OP_AUTH_VERIFY;
88         } else {
89                 plt_dp_err("Unknown aead operation\n");
90                 return -1;
91         }
92         switch (aead_form->algo) {
93         case RTE_CRYPTO_AEAD_AES_GCM:
94                 enc_type = ROC_SE_AES_GCM;
95                 cipher_key_len = 16;
96                 aes_gcm = 1;
97                 break;
98         case RTE_CRYPTO_AEAD_AES_CCM:
99                 plt_dp_err("Crypto: Unsupported cipher algo %u",
100                            aead_form->algo);
101                 return -1;
102         case RTE_CRYPTO_AEAD_CHACHA20_POLY1305:
103                 enc_type = ROC_SE_CHACHA20;
104                 auth_type = ROC_SE_POLY1305;
105                 cipher_key_len = 32;
106                 sess->chacha_poly = 1;
107                 break;
108         default:
109                 plt_dp_err("Crypto: Undefined cipher algo %u specified",
110                            aead_form->algo);
111                 return -1;
112         }
113         if (aead_form->key.length < cipher_key_len) {
114                 plt_dp_err("Invalid cipher params keylen %u",
115                            aead_form->key.length);
116                 return -1;
117         }
118         sess->zsk_flag = 0;
119         sess->aes_gcm = aes_gcm;
120         sess->mac_len = aead_form->digest_length;
121         sess->iv_offset = aead_form->iv.offset;
122         sess->iv_length = aead_form->iv.length;
123         sess->aad_length = aead_form->aad_length;
124
125         if (unlikely(roc_se_ciph_key_set(&sess->roc_se_ctx, enc_type,
126                                          aead_form->key.data,
127                                          aead_form->key.length, NULL)))
128                 return -1;
129
130         if (unlikely(roc_se_auth_key_set(&sess->roc_se_ctx, auth_type, NULL, 0,
131                                          aead_form->digest_length)))
132                 return -1;
133
134         return 0;
135 }
136
137 static __rte_always_inline int
138 fill_sess_cipher(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
139 {
140         struct rte_crypto_cipher_xform *c_form;
141         roc_se_cipher_type enc_type = 0; /* NULL Cipher type */
142         uint32_t cipher_key_len = 0;
143         uint8_t zsk_flag = 0, aes_ctr = 0, is_null = 0;
144
145         c_form = &xform->cipher;
146
147         if (c_form->op == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
148                 sess->cpt_op |= ROC_SE_OP_CIPHER_ENCRYPT;
149         else if (c_form->op == RTE_CRYPTO_CIPHER_OP_DECRYPT) {
150                 sess->cpt_op |= ROC_SE_OP_CIPHER_DECRYPT;
151                 if (xform->next != NULL &&
152                     xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
153                         /* Perform decryption followed by auth verify */
154                         sess->roc_se_ctx.template_w4.s.opcode_minor =
155                                 ROC_SE_FC_MINOR_OP_HMAC_FIRST;
156                 }
157         } else {
158                 plt_dp_err("Unknown cipher operation\n");
159                 return -1;
160         }
161
162         switch (c_form->algo) {
163         case RTE_CRYPTO_CIPHER_AES_CBC:
164                 enc_type = ROC_SE_AES_CBC;
165                 cipher_key_len = 16;
166                 break;
167         case RTE_CRYPTO_CIPHER_3DES_CBC:
168                 enc_type = ROC_SE_DES3_CBC;
169                 cipher_key_len = 24;
170                 break;
171         case RTE_CRYPTO_CIPHER_DES_CBC:
172                 /* DES is implemented using 3DES in hardware */
173                 enc_type = ROC_SE_DES3_CBC;
174                 cipher_key_len = 8;
175                 break;
176         case RTE_CRYPTO_CIPHER_AES_CTR:
177                 enc_type = ROC_SE_AES_CTR;
178                 cipher_key_len = 16;
179                 aes_ctr = 1;
180                 break;
181         case RTE_CRYPTO_CIPHER_NULL:
182                 enc_type = 0;
183                 is_null = 1;
184                 break;
185         case RTE_CRYPTO_CIPHER_KASUMI_F8:
186                 enc_type = ROC_SE_KASUMI_F8_ECB;
187                 cipher_key_len = 16;
188                 zsk_flag = ROC_SE_K_F8;
189                 break;
190         case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
191                 enc_type = ROC_SE_SNOW3G_UEA2;
192                 cipher_key_len = 16;
193                 zsk_flag = ROC_SE_ZS_EA;
194                 break;
195         case RTE_CRYPTO_CIPHER_ZUC_EEA3:
196                 enc_type = ROC_SE_ZUC_EEA3;
197                 cipher_key_len = 16;
198                 zsk_flag = ROC_SE_ZS_EA;
199                 break;
200         case RTE_CRYPTO_CIPHER_AES_XTS:
201                 enc_type = ROC_SE_AES_XTS;
202                 cipher_key_len = 16;
203                 break;
204         case RTE_CRYPTO_CIPHER_3DES_ECB:
205                 enc_type = ROC_SE_DES3_ECB;
206                 cipher_key_len = 24;
207                 break;
208         case RTE_CRYPTO_CIPHER_AES_ECB:
209                 enc_type = ROC_SE_AES_ECB;
210                 cipher_key_len = 16;
211                 break;
212         case RTE_CRYPTO_CIPHER_3DES_CTR:
213         case RTE_CRYPTO_CIPHER_AES_F8:
214         case RTE_CRYPTO_CIPHER_ARC4:
215                 plt_dp_err("Crypto: Unsupported cipher algo %u", c_form->algo);
216                 return -1;
217         default:
218                 plt_dp_err("Crypto: Undefined cipher algo %u specified",
219                            c_form->algo);
220                 return -1;
221         }
222
223         if (c_form->key.length < cipher_key_len) {
224                 plt_dp_err("Invalid cipher params keylen %u",
225                            c_form->key.length);
226                 return -1;
227         }
228
229         sess->zsk_flag = zsk_flag;
230         sess->aes_gcm = 0;
231         sess->aes_ctr = aes_ctr;
232         sess->iv_offset = c_form->iv.offset;
233         sess->iv_length = c_form->iv.length;
234         sess->is_null = is_null;
235
236         if (unlikely(roc_se_ciph_key_set(&sess->roc_se_ctx, enc_type,
237                                          c_form->key.data, c_form->key.length,
238                                          NULL)))
239                 return -1;
240
241         return 0;
242 }
243
244 static __rte_always_inline int
245 fill_sess_auth(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
246 {
247         struct rte_crypto_auth_xform *a_form;
248         roc_se_auth_type auth_type = 0; /* NULL Auth type */
249         uint8_t zsk_flag = 0, aes_gcm = 0, is_null = 0;
250
251         if (xform->next != NULL &&
252             xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
253             xform->next->cipher.op == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
254                 /* Perform auth followed by encryption */
255                 sess->roc_se_ctx.template_w4.s.opcode_minor =
256                         ROC_SE_FC_MINOR_OP_HMAC_FIRST;
257         }
258
259         a_form = &xform->auth;
260
261         if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY)
262                 sess->cpt_op |= ROC_SE_OP_AUTH_VERIFY;
263         else if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE)
264                 sess->cpt_op |= ROC_SE_OP_AUTH_GENERATE;
265         else {
266                 plt_dp_err("Unknown auth operation");
267                 return -1;
268         }
269
270         switch (a_form->algo) {
271         case RTE_CRYPTO_AUTH_SHA1_HMAC:
272                 /* Fall through */
273         case RTE_CRYPTO_AUTH_SHA1:
274                 auth_type = ROC_SE_SHA1_TYPE;
275                 break;
276         case RTE_CRYPTO_AUTH_SHA256_HMAC:
277         case RTE_CRYPTO_AUTH_SHA256:
278                 auth_type = ROC_SE_SHA2_SHA256;
279                 break;
280         case RTE_CRYPTO_AUTH_SHA512_HMAC:
281         case RTE_CRYPTO_AUTH_SHA512:
282                 auth_type = ROC_SE_SHA2_SHA512;
283                 break;
284         case RTE_CRYPTO_AUTH_AES_GMAC:
285                 auth_type = ROC_SE_GMAC_TYPE;
286                 aes_gcm = 1;
287                 break;
288         case RTE_CRYPTO_AUTH_SHA224_HMAC:
289         case RTE_CRYPTO_AUTH_SHA224:
290                 auth_type = ROC_SE_SHA2_SHA224;
291                 break;
292         case RTE_CRYPTO_AUTH_SHA384_HMAC:
293         case RTE_CRYPTO_AUTH_SHA384:
294                 auth_type = ROC_SE_SHA2_SHA384;
295                 break;
296         case RTE_CRYPTO_AUTH_MD5_HMAC:
297         case RTE_CRYPTO_AUTH_MD5:
298                 auth_type = ROC_SE_MD5_TYPE;
299                 break;
300         case RTE_CRYPTO_AUTH_KASUMI_F9:
301                 auth_type = ROC_SE_KASUMI_F9_ECB;
302                 /*
303                  * Indicate that direction needs to be taken out
304                  * from end of src
305                  */
306                 zsk_flag = ROC_SE_K_F9;
307                 break;
308         case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
309                 auth_type = ROC_SE_SNOW3G_UIA2;
310                 zsk_flag = ROC_SE_ZS_IA;
311                 break;
312         case RTE_CRYPTO_AUTH_ZUC_EIA3:
313                 auth_type = ROC_SE_ZUC_EIA3;
314                 zsk_flag = ROC_SE_ZS_IA;
315                 break;
316         case RTE_CRYPTO_AUTH_NULL:
317                 auth_type = 0;
318                 is_null = 1;
319                 break;
320         case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
321         case RTE_CRYPTO_AUTH_AES_CMAC:
322         case RTE_CRYPTO_AUTH_AES_CBC_MAC:
323                 plt_dp_err("Crypto: Unsupported hash algo %u", a_form->algo);
324                 return -1;
325         default:
326                 plt_dp_err("Crypto: Undefined Hash algo %u specified",
327                            a_form->algo);
328                 return -1;
329         }
330
331         sess->zsk_flag = zsk_flag;
332         sess->aes_gcm = aes_gcm;
333         sess->mac_len = a_form->digest_length;
334         sess->is_null = is_null;
335         if (zsk_flag) {
336                 sess->auth_iv_offset = a_form->iv.offset;
337                 sess->auth_iv_length = a_form->iv.length;
338         }
339         if (unlikely(roc_se_auth_key_set(&sess->roc_se_ctx, auth_type,
340                                          a_form->key.data, a_form->key.length,
341                                          a_form->digest_length)))
342                 return -1;
343
344         return 0;
345 }
346
347 static __rte_always_inline int
348 fill_sess_gmac(struct rte_crypto_sym_xform *xform, struct cnxk_se_sess *sess)
349 {
350         struct rte_crypto_auth_xform *a_form;
351         roc_se_cipher_type enc_type = 0; /* NULL Cipher type */
352         roc_se_auth_type auth_type = 0;  /* NULL Auth type */
353
354         a_form = &xform->auth;
355
356         if (a_form->op == RTE_CRYPTO_AUTH_OP_GENERATE)
357                 sess->cpt_op |= ROC_SE_OP_ENCODE;
358         else if (a_form->op == RTE_CRYPTO_AUTH_OP_VERIFY)
359                 sess->cpt_op |= ROC_SE_OP_DECODE;
360         else {
361                 plt_dp_err("Unknown auth operation");
362                 return -1;
363         }
364
365         switch (a_form->algo) {
366         case RTE_CRYPTO_AUTH_AES_GMAC:
367                 enc_type = ROC_SE_AES_GCM;
368                 auth_type = ROC_SE_GMAC_TYPE;
369                 break;
370         default:
371                 plt_dp_err("Crypto: Undefined cipher algo %u specified",
372                            a_form->algo);
373                 return -1;
374         }
375
376         sess->zsk_flag = 0;
377         sess->aes_gcm = 0;
378         sess->is_gmac = 1;
379         sess->iv_offset = a_form->iv.offset;
380         sess->iv_length = a_form->iv.length;
381         sess->mac_len = a_form->digest_length;
382
383         if (unlikely(roc_se_ciph_key_set(&sess->roc_se_ctx, enc_type,
384                                          a_form->key.data, a_form->key.length,
385                                          NULL)))
386                 return -1;
387
388         if (unlikely(roc_se_auth_key_set(&sess->roc_se_ctx, auth_type, NULL, 0,
389                                          a_form->digest_length)))
390                 return -1;
391
392         return 0;
393 }
394
395 #endif /*_CNXK_SE_H_ */