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