net/octeontx2: support non-ethernet L2 header
[dpdk.git] / drivers / crypto / octeontx2 / otx2_ipsec_fp.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2020 Marvell International Ltd.
3  */
4
5 #ifndef __OTX2_IPSEC_FP_H__
6 #define __OTX2_IPSEC_FP_H__
7
8 #include <rte_crypto_sym.h>
9 #include <rte_security.h>
10
11 /* Macros for anti replay and ESN */
12 #define OTX2_IPSEC_MAX_REPLAY_WIN_SZ    1024
13
14 struct otx2_ipsec_fp_res_hdr {
15         uint32_t spi;
16         uint32_t seq_no_lo;
17         uint32_t seq_no_hi;
18         uint32_t rsvd;
19 };
20
21 enum {
22         OTX2_IPSEC_FP_SA_DIRECTION_INBOUND = 0,
23         OTX2_IPSEC_FP_SA_DIRECTION_OUTBOUND = 1,
24 };
25
26 enum {
27         OTX2_IPSEC_FP_SA_IP_VERSION_4 = 0,
28         OTX2_IPSEC_FP_SA_IP_VERSION_6 = 1,
29 };
30
31 enum {
32         OTX2_IPSEC_FP_SA_MODE_TRANSPORT = 0,
33         OTX2_IPSEC_FP_SA_MODE_TUNNEL = 1,
34 };
35
36 enum {
37         OTX2_IPSEC_FP_SA_PROTOCOL_AH = 0,
38         OTX2_IPSEC_FP_SA_PROTOCOL_ESP = 1,
39 };
40
41 enum {
42         OTX2_IPSEC_FP_SA_AES_KEY_LEN_128 = 1,
43         OTX2_IPSEC_FP_SA_AES_KEY_LEN_192 = 2,
44         OTX2_IPSEC_FP_SA_AES_KEY_LEN_256 = 3,
45 };
46
47 enum {
48         OTX2_IPSEC_FP_SA_ENC_NULL = 0,
49         OTX2_IPSEC_FP_SA_ENC_DES_CBC = 1,
50         OTX2_IPSEC_FP_SA_ENC_3DES_CBC = 2,
51         OTX2_IPSEC_FP_SA_ENC_AES_CBC = 3,
52         OTX2_IPSEC_FP_SA_ENC_AES_CTR = 4,
53         OTX2_IPSEC_FP_SA_ENC_AES_GCM = 5,
54         OTX2_IPSEC_FP_SA_ENC_AES_CCM = 6,
55 };
56
57 enum {
58         OTX2_IPSEC_FP_SA_AUTH_NULL = 0,
59         OTX2_IPSEC_FP_SA_AUTH_MD5 = 1,
60         OTX2_IPSEC_FP_SA_AUTH_SHA1 = 2,
61         OTX2_IPSEC_FP_SA_AUTH_SHA2_224 = 3,
62         OTX2_IPSEC_FP_SA_AUTH_SHA2_256 = 4,
63         OTX2_IPSEC_FP_SA_AUTH_SHA2_384 = 5,
64         OTX2_IPSEC_FP_SA_AUTH_SHA2_512 = 6,
65         OTX2_IPSEC_FP_SA_AUTH_AES_GMAC = 7,
66         OTX2_IPSEC_FP_SA_AUTH_AES_XCBC_128 = 8,
67 };
68
69 enum {
70         OTX2_IPSEC_FP_SA_FRAG_POST = 0,
71         OTX2_IPSEC_FP_SA_FRAG_PRE = 1,
72 };
73
74 enum {
75         OTX2_IPSEC_FP_SA_ENCAP_NONE = 0,
76         OTX2_IPSEC_FP_SA_ENCAP_UDP = 1,
77 };
78
79 struct otx2_ipsec_fp_sa_ctl {
80         rte_be32_t spi          : 32;
81         uint64_t exp_proto_inter_frag : 8;
82         uint64_t rsvd_42_40   : 3;
83         uint64_t esn_en       : 1;
84         uint64_t rsvd_45_44   : 2;
85         uint64_t encap_type   : 2;
86         uint64_t enc_type     : 3;
87         uint64_t rsvd_48      : 1;
88         uint64_t auth_type    : 4;
89         uint64_t valid        : 1;
90         uint64_t direction    : 1;
91         uint64_t outer_ip_ver : 1;
92         uint64_t inner_ip_ver : 1;
93         uint64_t ipsec_mode   : 1;
94         uint64_t ipsec_proto  : 1;
95         uint64_t aes_key_len  : 2;
96 };
97
98 struct otx2_ipsec_fp_out_sa {
99         /* w0 */
100         struct otx2_ipsec_fp_sa_ctl ctl;
101
102         /* w1 */
103         uint8_t nonce[4];
104         uint16_t udp_src;
105         uint16_t udp_dst;
106
107         /* w2 */
108         uint32_t ip_src;
109         uint32_t ip_dst;
110
111         /* w3-w6 */
112         uint8_t cipher_key[32];
113
114         /* w7-w12 */
115         uint8_t hmac_key[48];
116 };
117
118 struct otx2_ipsec_replay {
119         rte_spinlock_t lock;
120         uint32_t winb;
121         uint32_t wint;
122         uint64_t base; /**< base of the anti-replay window */
123         uint64_t window[17]; /**< anti-replay window */
124 };
125
126 struct otx2_ipsec_fp_in_sa {
127         /* w0 */
128         struct otx2_ipsec_fp_sa_ctl ctl;
129
130         /* w1 */
131         uint8_t nonce[4]; /* Only for AES-GCM */
132         uint32_t unused;
133
134         /* w2 */
135         uint32_t esn_hi;
136         uint32_t esn_low;
137
138         /* w3-w6 */
139         uint8_t cipher_key[32];
140
141         /* w7-w12 */
142         uint8_t hmac_key[48];
143
144         RTE_STD_C11
145         union {
146                 void *userdata;
147                 uint64_t udata64;
148         };
149         union {
150                 struct otx2_ipsec_replay *replay;
151                 uint64_t replay64;
152         };
153         uint32_t replay_win_sz;
154
155         uint32_t reserved1;
156 };
157
158 static inline int
159 ipsec_fp_xform_cipher_verify(struct rte_crypto_sym_xform *xform)
160 {
161         if (xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
162                 switch (xform->cipher.key.length) {
163                 case 16:
164                 case 24:
165                 case 32:
166                         break;
167                 default:
168                         return -ENOTSUP;
169                 }
170                 return 0;
171         }
172
173         return -ENOTSUP;
174 }
175
176 static inline int
177 ipsec_fp_xform_auth_verify(struct rte_crypto_sym_xform *xform)
178 {
179         uint16_t keylen = xform->auth.key.length;
180
181         if (xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) {
182                 if (keylen >= 20 && keylen <= 64)
183                         return 0;
184         }
185
186         return -ENOTSUP;
187 }
188
189 static inline int
190 ipsec_fp_xform_aead_verify(struct rte_security_ipsec_xform *ipsec,
191                            struct rte_crypto_sym_xform *xform)
192 {
193         if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
194             xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
195                 return -EINVAL;
196
197         if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
198             xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
199                 return -EINVAL;
200
201         if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
202                 switch (xform->aead.key.length) {
203                 case 16:
204                 case 24:
205                 case 32:
206                         break;
207                 default:
208                         return -EINVAL;
209                 }
210                 return 0;
211         }
212
213         return -ENOTSUP;
214 }
215
216 static inline int
217 ipsec_fp_xform_verify(struct rte_security_ipsec_xform *ipsec,
218                       struct rte_crypto_sym_xform *xform)
219 {
220         struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
221         int ret;
222
223         if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
224                 return ipsec_fp_xform_aead_verify(ipsec, xform);
225
226         if (xform->next == NULL)
227                 return -EINVAL;
228
229         if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
230                 /* Ingress */
231                 if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
232                     xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
233                         return -EINVAL;
234                 auth_xform = xform;
235                 cipher_xform = xform->next;
236         } else {
237                 /* Egress */
238                 if (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
239                     xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
240                         return -EINVAL;
241                 cipher_xform = xform;
242                 auth_xform = xform->next;
243         }
244
245         ret = ipsec_fp_xform_cipher_verify(cipher_xform);
246         if (ret)
247                 return ret;
248
249         ret = ipsec_fp_xform_auth_verify(auth_xform);
250         if (ret)
251                 return ret;
252
253         return 0;
254 }
255
256 static inline int
257 ipsec_fp_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
258                     struct rte_crypto_sym_xform *xform,
259                     struct otx2_ipsec_fp_sa_ctl *ctl)
260 {
261         struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
262         int aes_key_len;
263
264         if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
265                 ctl->direction = OTX2_IPSEC_FP_SA_DIRECTION_OUTBOUND;
266                 cipher_xform = xform;
267                 auth_xform = xform->next;
268         } else if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
269                 ctl->direction = OTX2_IPSEC_FP_SA_DIRECTION_INBOUND;
270                 auth_xform = xform;
271                 cipher_xform = xform->next;
272         } else {
273                 return -EINVAL;
274         }
275
276         if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
277                 if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
278                         ctl->outer_ip_ver = OTX2_IPSEC_FP_SA_IP_VERSION_4;
279                 else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
280                         ctl->outer_ip_ver = OTX2_IPSEC_FP_SA_IP_VERSION_6;
281                 else
282                         return -EINVAL;
283         }
284
285         ctl->inner_ip_ver = OTX2_IPSEC_FP_SA_IP_VERSION_4;
286
287         if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT)
288                 ctl->ipsec_mode = OTX2_IPSEC_FP_SA_MODE_TRANSPORT;
289         else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
290                 ctl->ipsec_mode = OTX2_IPSEC_FP_SA_MODE_TUNNEL;
291         else
292                 return -EINVAL;
293
294         if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
295                 ctl->ipsec_proto = OTX2_IPSEC_FP_SA_PROTOCOL_AH;
296         else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP)
297                 ctl->ipsec_proto = OTX2_IPSEC_FP_SA_PROTOCOL_ESP;
298         else
299                 return -EINVAL;
300
301         if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
302                 if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
303                         ctl->enc_type = OTX2_IPSEC_FP_SA_ENC_AES_GCM;
304                         aes_key_len = xform->aead.key.length;
305                 } else {
306                         return -ENOTSUP;
307                 }
308         } else if (cipher_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
309                 ctl->enc_type = OTX2_IPSEC_FP_SA_ENC_AES_CBC;
310                 aes_key_len = cipher_xform->cipher.key.length;
311         } else {
312                 return -ENOTSUP;
313         }
314
315         switch (aes_key_len) {
316         case 16:
317                 ctl->aes_key_len = OTX2_IPSEC_FP_SA_AES_KEY_LEN_128;
318                 break;
319         case 24:
320                 ctl->aes_key_len = OTX2_IPSEC_FP_SA_AES_KEY_LEN_192;
321                 break;
322         case 32:
323                 ctl->aes_key_len = OTX2_IPSEC_FP_SA_AES_KEY_LEN_256;
324                 break;
325         default:
326                 return -EINVAL;
327         }
328
329         if (xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
330                 switch (auth_xform->auth.algo) {
331                 case RTE_CRYPTO_AUTH_NULL:
332                         ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_NULL;
333                         break;
334                 case RTE_CRYPTO_AUTH_MD5_HMAC:
335                         ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_MD5;
336                         break;
337                 case RTE_CRYPTO_AUTH_SHA1_HMAC:
338                         ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_SHA1;
339                         break;
340                 case RTE_CRYPTO_AUTH_SHA224_HMAC:
341                         ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_SHA2_224;
342                         break;
343                 case RTE_CRYPTO_AUTH_SHA256_HMAC:
344                         ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_SHA2_256;
345                         break;
346                 case RTE_CRYPTO_AUTH_SHA384_HMAC:
347                         ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_SHA2_384;
348                         break;
349                 case RTE_CRYPTO_AUTH_SHA512_HMAC:
350                         ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_SHA2_512;
351                         break;
352                 case RTE_CRYPTO_AUTH_AES_GMAC:
353                         ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_AES_GMAC;
354                         break;
355                 case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
356                         ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_AES_XCBC_128;
357                         break;
358                 default:
359                         return -ENOTSUP;
360                 }
361         }
362
363         if (ipsec->options.esn == 1)
364                 ctl->esn_en = 1;
365
366         ctl->spi = rte_cpu_to_be_32(ipsec->spi);
367         ctl->valid = 1;
368
369         return 0;
370 }
371
372 #endif /* __OTX2_IPSEC_FP_H__ */