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