examples/vhost: fix use after free on drain
[dpdk.git] / drivers / crypto / octeontx2 / otx2_ipsec_po.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2020 Marvell International Ltd.
3  */
4
5 #ifndef __OTX2_IPSEC_PO_H__
6 #define __OTX2_IPSEC_PO_H__
7
8 #include <rte_crypto_sym.h>
9 #include <rte_ip.h>
10 #include <rte_security.h>
11
12 #define OTX2_IPSEC_PO_AES_GCM_INB_CTX_LEN    0x09
13
14 #define OTX2_IPSEC_PO_PER_PKT_IV  BIT(11)
15
16 #define OTX2_IPSEC_PO_WRITE_IPSEC_OUTB     0x20
17 #define OTX2_IPSEC_PO_WRITE_IPSEC_INB      0x21
18 #define OTX2_IPSEC_PO_PROCESS_IPSEC_OUTB   0x23
19 #define OTX2_IPSEC_PO_PROCESS_IPSEC_INB    0x24
20
21 #define OTX2_IPSEC_PO_INB_RPTR_HDR         0x8
22
23 enum otx2_ipsec_po_mode_type {
24         OTX2_IPSEC_PO_TRANSPORT = 1,
25         OTX2_IPSEC_PO_TUNNEL_IPV4,
26         OTX2_IPSEC_PO_TUNNEL_IPV6,
27 };
28
29 enum otx2_ipsec_po_comp_e {
30         OTX2_IPSEC_PO_CC_SUCCESS = 0x00,
31         OTX2_IPSEC_PO_CC_AUTH_UNSUPPORTED = 0xB0,
32         OTX2_IPSEC_PO_CC_ENCRYPT_UNSUPPORTED = 0xB1,
33 };
34
35 enum {
36         OTX2_IPSEC_PO_SA_DIRECTION_INBOUND = 0,
37         OTX2_IPSEC_PO_SA_DIRECTION_OUTBOUND = 1,
38 };
39
40 enum {
41         OTX2_IPSEC_PO_SA_IP_VERSION_4 = 0,
42         OTX2_IPSEC_PO_SA_IP_VERSION_6 = 1,
43 };
44
45 enum {
46         OTX2_IPSEC_PO_SA_MODE_TRANSPORT = 0,
47         OTX2_IPSEC_PO_SA_MODE_TUNNEL = 1,
48 };
49
50 enum {
51         OTX2_IPSEC_PO_SA_PROTOCOL_AH = 0,
52         OTX2_IPSEC_PO_SA_PROTOCOL_ESP = 1,
53 };
54
55 enum {
56         OTX2_IPSEC_PO_SA_AES_KEY_LEN_128 = 1,
57         OTX2_IPSEC_PO_SA_AES_KEY_LEN_192 = 2,
58         OTX2_IPSEC_PO_SA_AES_KEY_LEN_256 = 3,
59 };
60
61 enum {
62         OTX2_IPSEC_PO_SA_ENC_NULL = 0,
63         OTX2_IPSEC_PO_SA_ENC_DES_CBC = 1,
64         OTX2_IPSEC_PO_SA_ENC_3DES_CBC = 2,
65         OTX2_IPSEC_PO_SA_ENC_AES_CBC = 3,
66         OTX2_IPSEC_PO_SA_ENC_AES_CTR = 4,
67         OTX2_IPSEC_PO_SA_ENC_AES_GCM = 5,
68         OTX2_IPSEC_PO_SA_ENC_AES_CCM = 6,
69 };
70
71 enum {
72         OTX2_IPSEC_PO_SA_AUTH_NULL = 0,
73         OTX2_IPSEC_PO_SA_AUTH_MD5 = 1,
74         OTX2_IPSEC_PO_SA_AUTH_SHA1 = 2,
75         OTX2_IPSEC_PO_SA_AUTH_SHA2_224 = 3,
76         OTX2_IPSEC_PO_SA_AUTH_SHA2_256 = 4,
77         OTX2_IPSEC_PO_SA_AUTH_SHA2_384 = 5,
78         OTX2_IPSEC_PO_SA_AUTH_SHA2_512 = 6,
79         OTX2_IPSEC_PO_SA_AUTH_AES_GMAC = 7,
80         OTX2_IPSEC_PO_SA_AUTH_AES_XCBC_128 = 8,
81 };
82
83 enum {
84         OTX2_IPSEC_PO_SA_FRAG_POST = 0,
85         OTX2_IPSEC_PO_SA_FRAG_PRE = 1,
86 };
87
88 enum {
89         OTX2_IPSEC_PO_SA_ENCAP_NONE = 0,
90         OTX2_IPSEC_PO_SA_ENCAP_UDP = 1,
91 };
92
93 struct otx2_ipsec_po_out_hdr {
94         uint32_t ip_id;
95         uint32_t seq;
96         uint8_t iv[16];
97 };
98
99 union otx2_ipsec_po_bit_perfect_iv {
100         uint8_t aes_iv[16];
101         uint8_t des_iv[8];
102         struct {
103                 uint8_t nonce[4];
104                 uint8_t iv[8];
105                 uint8_t counter[4];
106         } gcm;
107 };
108
109 struct otx2_ipsec_po_traffic_selector {
110         rte_be16_t src_port[2];
111         rte_be16_t dst_port[2];
112         RTE_STD_C11
113         union {
114                 struct {
115                         rte_be32_t src_addr[2];
116                         rte_be32_t dst_addr[2];
117                 } ipv4;
118                 struct {
119                         uint8_t src_addr[32];
120                         uint8_t dst_addr[32];
121                 } ipv6;
122         };
123 };
124
125 struct otx2_ipsec_po_sa_ctl {
126         rte_be32_t spi          : 32;
127         uint64_t exp_proto_inter_frag : 8;
128         uint64_t rsvd_42_40   : 3;
129         uint64_t esn_en       : 1;
130         uint64_t rsvd_45_44   : 2;
131         uint64_t encap_type   : 2;
132         uint64_t enc_type     : 3;
133         uint64_t rsvd_48      : 1;
134         uint64_t auth_type    : 4;
135         uint64_t valid        : 1;
136         uint64_t direction    : 1;
137         uint64_t outer_ip_ver : 1;
138         uint64_t inner_ip_ver : 1;
139         uint64_t ipsec_mode   : 1;
140         uint64_t ipsec_proto  : 1;
141         uint64_t aes_key_len  : 2;
142 };
143
144 struct otx2_ipsec_po_in_sa {
145         /* w0 */
146         struct otx2_ipsec_po_sa_ctl ctl;
147
148         /* w1-w4 */
149         uint8_t cipher_key[32];
150
151         /* w5-w6 */
152         union otx2_ipsec_po_bit_perfect_iv iv;
153
154         /* w7 */
155         uint32_t esn_hi;
156         uint32_t esn_low;
157
158         /* w8 */
159         uint8_t udp_encap[8];
160
161         /* w9-w33 */
162         union {
163                 struct {
164                         uint8_t hmac_key[48];
165                         struct otx2_ipsec_po_traffic_selector selector;
166                 } aes_gcm;
167                 struct {
168                         uint8_t hmac_key[64];
169                         uint8_t hmac_iv[64];
170                         struct otx2_ipsec_po_traffic_selector selector;
171                 } sha2;
172         };
173         union {
174                 struct otx2_ipsec_replay *replay;
175                 uint64_t replay64;
176         };
177         uint32_t replay_win_sz;
178 };
179
180 struct otx2_ipsec_po_ip_template {
181         RTE_STD_C11
182         union {
183                 struct {
184                         struct rte_ipv4_hdr ipv4_hdr;
185                         uint16_t udp_src;
186                         uint16_t udp_dst;
187                 } ip4;
188                 struct {
189                         struct rte_ipv6_hdr ipv6_hdr;
190                         uint16_t udp_src;
191                         uint16_t udp_dst;
192                 } ip6;
193         };
194 };
195
196 struct otx2_ipsec_po_out_sa {
197         /* w0 */
198         struct otx2_ipsec_po_sa_ctl ctl;
199
200         /* w1-w4 */
201         uint8_t cipher_key[32];
202
203         /* w5-w6 */
204         union otx2_ipsec_po_bit_perfect_iv iv;
205
206         /* w7 */
207         uint32_t esn_hi;
208         uint32_t esn_low;
209
210         /* w8-w55 */
211         union {
212                 struct {
213                         struct otx2_ipsec_po_ip_template template;
214                 } aes_gcm;
215                 struct {
216                         uint8_t hmac_key[24];
217                         uint8_t unused[24];
218                         struct otx2_ipsec_po_ip_template template;
219                 } sha1;
220                 struct {
221                         uint8_t hmac_key[64];
222                         uint8_t hmac_iv[64];
223                         struct otx2_ipsec_po_ip_template template;
224                 } sha2;
225         };
226 };
227
228 static inline int
229 ipsec_po_xform_cipher_verify(struct rte_crypto_sym_xform *xform)
230 {
231         if (xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
232                 switch (xform->cipher.key.length) {
233                 case 16:
234                 case 24:
235                 case 32:
236                         break;
237                 default:
238                         return -ENOTSUP;
239                 }
240                 return 0;
241         }
242
243         return -ENOTSUP;
244 }
245
246 static inline int
247 ipsec_po_xform_auth_verify(struct rte_crypto_sym_xform *xform)
248 {
249         uint16_t keylen = xform->auth.key.length;
250
251         if (xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) {
252                 if (keylen >= 20 && keylen <= 64)
253                         return 0;
254         } else if (xform->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC) {
255                 if (keylen >= 32 && keylen <= 64)
256                         return 0;
257         }
258
259         return -ENOTSUP;
260 }
261
262 static inline int
263 ipsec_po_xform_aead_verify(struct rte_security_ipsec_xform *ipsec,
264                            struct rte_crypto_sym_xform *xform)
265 {
266         if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
267             xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
268                 return -EINVAL;
269
270         if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
271             xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
272                 return -EINVAL;
273
274         if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
275                 switch (xform->aead.key.length) {
276                 case 16:
277                 case 24:
278                 case 32:
279                         break;
280                 default:
281                         return -EINVAL;
282                 }
283                 return 0;
284         }
285
286         return -ENOTSUP;
287 }
288
289 static inline int
290 ipsec_po_xform_verify(struct rte_security_ipsec_xform *ipsec,
291                       struct rte_crypto_sym_xform *xform)
292 {
293         struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
294         int ret;
295
296         if (ipsec->life.bytes_hard_limit != 0 ||
297             ipsec->life.bytes_soft_limit != 0 ||
298             ipsec->life.packets_hard_limit != 0 ||
299             ipsec->life.packets_soft_limit != 0)
300                 return -ENOTSUP;
301
302         if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
303                 return ipsec_po_xform_aead_verify(ipsec, xform);
304
305         if (xform->next == NULL)
306                 return -EINVAL;
307
308         if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
309                 /* Ingress */
310                 if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
311                     xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
312                         return -EINVAL;
313                 auth_xform = xform;
314                 cipher_xform = xform->next;
315         } else {
316                 /* Egress */
317                 if (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
318                     xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
319                         return -EINVAL;
320                 cipher_xform = xform;
321                 auth_xform = xform->next;
322         }
323
324         ret = ipsec_po_xform_cipher_verify(cipher_xform);
325         if (ret)
326                 return ret;
327
328         ret = ipsec_po_xform_auth_verify(auth_xform);
329         if (ret)
330                 return ret;
331
332         return 0;
333 }
334
335 static inline int
336 ipsec_po_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
337                     struct rte_crypto_sym_xform *xform,
338                     struct otx2_ipsec_po_sa_ctl *ctl)
339 {
340         struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
341         int aes_key_len;
342
343         if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
344                 ctl->direction = OTX2_IPSEC_PO_SA_DIRECTION_OUTBOUND;
345                 cipher_xform = xform;
346                 auth_xform = xform->next;
347         } else if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
348                 ctl->direction = OTX2_IPSEC_PO_SA_DIRECTION_INBOUND;
349                 auth_xform = xform;
350                 cipher_xform = xform->next;
351         } else {
352                 return -EINVAL;
353         }
354
355         if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
356                 if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
357                         ctl->outer_ip_ver = OTX2_IPSEC_PO_SA_IP_VERSION_4;
358                 else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
359                         ctl->outer_ip_ver = OTX2_IPSEC_PO_SA_IP_VERSION_6;
360                 else
361                         return -EINVAL;
362         }
363
364         ctl->inner_ip_ver = ctl->outer_ip_ver;
365
366         if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT)
367                 ctl->ipsec_mode = OTX2_IPSEC_PO_SA_MODE_TRANSPORT;
368         else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
369                 ctl->ipsec_mode = OTX2_IPSEC_PO_SA_MODE_TUNNEL;
370         else
371                 return -EINVAL;
372
373         if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
374                 ctl->ipsec_proto = OTX2_IPSEC_PO_SA_PROTOCOL_AH;
375         else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP)
376                 ctl->ipsec_proto = OTX2_IPSEC_PO_SA_PROTOCOL_ESP;
377         else
378                 return -EINVAL;
379
380         if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
381                 if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
382                         ctl->enc_type = OTX2_IPSEC_PO_SA_ENC_AES_GCM;
383                         aes_key_len = xform->aead.key.length;
384                 } else {
385                         return -ENOTSUP;
386                 }
387         } else if (cipher_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
388                 ctl->enc_type = OTX2_IPSEC_PO_SA_ENC_AES_CBC;
389                 aes_key_len = cipher_xform->cipher.key.length;
390         } else {
391                 return -ENOTSUP;
392         }
393
394
395         switch (aes_key_len) {
396         case 16:
397                 ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_128;
398                 break;
399         case 24:
400                 ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_192;
401                 break;
402         case 32:
403                 ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_256;
404                 break;
405         default:
406                 return -EINVAL;
407         }
408
409         if (xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
410                 switch (auth_xform->auth.algo) {
411                 case RTE_CRYPTO_AUTH_NULL:
412                         ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_NULL;
413                         break;
414                 case RTE_CRYPTO_AUTH_MD5_HMAC:
415                         ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_MD5;
416                         break;
417                 case RTE_CRYPTO_AUTH_SHA1_HMAC:
418                         ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA1;
419                         break;
420                 case RTE_CRYPTO_AUTH_SHA224_HMAC:
421                         ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_224;
422                         break;
423                 case RTE_CRYPTO_AUTH_SHA256_HMAC:
424                         ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_256;
425                         break;
426                 case RTE_CRYPTO_AUTH_SHA384_HMAC:
427                         ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_384;
428                         break;
429                 case RTE_CRYPTO_AUTH_SHA512_HMAC:
430                         ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_512;
431                         break;
432                 case RTE_CRYPTO_AUTH_AES_GMAC:
433                         ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_AES_GMAC;
434                         break;
435                 case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
436                         ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_AES_XCBC_128;
437                         break;
438                 default:
439                         return -ENOTSUP;
440                 }
441         }
442
443         if (ipsec->options.esn)
444                 ctl->esn_en = 1;
445
446         if (ipsec->options.udp_encap == 1)
447                 ctl->encap_type = OTX2_IPSEC_PO_SA_ENCAP_UDP;
448
449         ctl->spi = rte_cpu_to_be_32(ipsec->spi);
450         ctl->valid = 1;
451
452         return 0;
453 }
454
455 #endif /* __OTX2_IPSEC_PO_H__ */