crypto/cnxk: support inner checksum
[dpdk.git] / drivers / crypto / cnxk / cnxk_ipsec.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2021 Marvell.
3  */
4 #ifndef __CNXK_IPSEC_H__
5 #define __CNXK_IPSEC_H__
6
7 #include <rte_security.h>
8 #include <rte_security_driver.h>
9
10 #include "roc_api.h"
11
12 extern struct rte_security_ops cnxk_sec_ops;
13
14 struct cnxk_cpt_inst_tmpl {
15         uint64_t w2;
16         uint64_t w4;
17         uint64_t w7;
18 };
19
20 static inline int
21 ipsec_xform_cipher_verify(struct rte_crypto_sym_xform *crypto_xform)
22 {
23         if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
24                 switch (crypto_xform->cipher.key.length) {
25                 case 16:
26                 case 24:
27                 case 32:
28                         break;
29                 default:
30                         return -ENOTSUP;
31                 }
32                 return 0;
33         }
34
35         return -ENOTSUP;
36 }
37
38 static inline int
39 ipsec_xform_auth_verify(struct rte_crypto_sym_xform *crypto_xform)
40 {
41         uint16_t keylen = crypto_xform->auth.key.length;
42
43         if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) {
44                 if (keylen >= 20 && keylen <= 64)
45                         return 0;
46         } else if (roc_model_is_cn9k() &&
47                    (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC)) {
48                 if (keylen >= 32 && keylen <= 64)
49                         return 0;
50         }
51
52         return -ENOTSUP;
53 }
54
55 static inline int
56 ipsec_xform_aead_verify(struct rte_security_ipsec_xform *ipsec_xform,
57                         struct rte_crypto_sym_xform *crypto_xform)
58 {
59         if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
60             crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
61                 return -EINVAL;
62
63         if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
64             crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
65                 return -EINVAL;
66
67         if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
68                 switch (crypto_xform->aead.key.length) {
69                 case 16:
70                 case 24:
71                 case 32:
72                         break;
73                 default:
74                         return -EINVAL;
75                 }
76                 return 0;
77         }
78
79         return -ENOTSUP;
80 }
81
82 static inline int
83 cnxk_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec_xform,
84                         struct rte_crypto_sym_xform *crypto_xform)
85 {
86         struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
87         int ret;
88
89         if ((ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
90             (ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_EGRESS))
91                 return -EINVAL;
92
93         if ((ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_ESP) &&
94             (ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_AH))
95                 return -EINVAL;
96
97         if ((ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) &&
98             (ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL))
99                 return -EINVAL;
100
101         if ((ipsec_xform->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) &&
102             (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV4) &&
103             (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV6))
104                 return -EINVAL;
105
106         if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
107                 return ipsec_xform_aead_verify(ipsec_xform, crypto_xform);
108
109         if (crypto_xform->next == NULL)
110                 return -EINVAL;
111
112         if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
113                 /* Ingress */
114                 if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
115                     crypto_xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
116                         return -EINVAL;
117                 auth_xform = crypto_xform;
118                 cipher_xform = crypto_xform->next;
119         } else {
120                 /* Egress */
121                 if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
122                     crypto_xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
123                         return -EINVAL;
124                 cipher_xform = crypto_xform;
125                 auth_xform = crypto_xform->next;
126         }
127
128         ret = ipsec_xform_cipher_verify(cipher_xform);
129         if (ret)
130                 return ret;
131
132         return ipsec_xform_auth_verify(auth_xform);
133 }
134 #endif /* __CNXK_IPSEC_H__ */