crypto/cnxk: add per packet IV in lookaside IPsec debug
[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_NULL)
24                 return 0;
25
26         if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC ||
27             crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CTR) {
28                 switch (crypto_xform->cipher.key.length) {
29                 case 16:
30                 case 24:
31                 case 32:
32                         break;
33                 default:
34                         return -ENOTSUP;
35                 }
36                 return 0;
37         }
38
39         return -ENOTSUP;
40 }
41
42 static inline int
43 ipsec_xform_auth_verify(struct rte_crypto_sym_xform *crypto_xform)
44 {
45         uint16_t keylen = crypto_xform->auth.key.length;
46
47         if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_NULL)
48                 return 0;
49
50         if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) {
51                 if (keylen >= 20 && keylen <= 64)
52                         return 0;
53         } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC) {
54                 if (keylen >= 32 && keylen <= 64)
55                         return 0;
56         } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA384_HMAC) {
57                 if (keylen == 48)
58                         return 0;
59         } else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA512_HMAC) {
60                 if (keylen == 64)
61                         return 0;
62         }
63
64         if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC &&
65             keylen == ROC_CPT_AES_XCBC_KEY_LENGTH)
66                 return 0;
67
68         return -ENOTSUP;
69 }
70
71 static inline int
72 ipsec_xform_aead_verify(struct rte_security_ipsec_xform *ipsec_xform,
73                         struct rte_crypto_sym_xform *crypto_xform)
74 {
75         if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
76             crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
77                 return -EINVAL;
78
79         if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
80             crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
81                 return -EINVAL;
82
83         if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
84                 switch (crypto_xform->aead.key.length) {
85                 case 16:
86                 case 24:
87                 case 32:
88                         break;
89                 default:
90                         return -EINVAL;
91                 }
92                 return 0;
93         }
94
95         return -ENOTSUP;
96 }
97
98 static inline int
99 cnxk_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec_xform,
100                         struct rte_crypto_sym_xform *crypto_xform)
101 {
102         struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
103         int ret;
104
105         if ((ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
106             (ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_EGRESS))
107                 return -EINVAL;
108
109         if ((ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_ESP) &&
110             (ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_AH))
111                 return -EINVAL;
112
113         if ((ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) &&
114             (ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL))
115                 return -EINVAL;
116
117         if ((ipsec_xform->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) &&
118             (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV4) &&
119             (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV6))
120                 return -EINVAL;
121
122         if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
123                 return ipsec_xform_aead_verify(ipsec_xform, crypto_xform);
124
125         if (crypto_xform->next == NULL)
126                 return -EINVAL;
127
128         if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
129                 /* Ingress */
130                 if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
131                     crypto_xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
132                         return -EINVAL;
133                 auth_xform = crypto_xform;
134                 cipher_xform = crypto_xform->next;
135         } else {
136                 /* Egress */
137                 if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
138                     crypto_xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
139                         return -EINVAL;
140                 cipher_xform = crypto_xform;
141                 auth_xform = crypto_xform->next;
142         }
143
144         ret = ipsec_xform_cipher_verify(cipher_xform);
145         if (ret)
146                 return ret;
147
148         return ipsec_xform_auth_verify(auth_xform);
149 }
150 #endif /* __CNXK_IPSEC_H__ */