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