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