crypto/cnxk: fix KASUMI input length
[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_NULL)
44                 return 0;
45
46         if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) {
47                 if (keylen >= 20 && keylen <= 64)
48                         return 0;
49         } else if (roc_model_is_cn9k() &&
50                    (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC)) {
51                 if (keylen >= 32 && keylen <= 64)
52                         return 0;
53         }
54
55         return -ENOTSUP;
56 }
57
58 static inline int
59 ipsec_xform_aead_verify(struct rte_security_ipsec_xform *ipsec_xform,
60                         struct rte_crypto_sym_xform *crypto_xform)
61 {
62         if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
63             crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
64                 return -EINVAL;
65
66         if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
67             crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
68                 return -EINVAL;
69
70         if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
71                 switch (crypto_xform->aead.key.length) {
72                 case 16:
73                 case 24:
74                 case 32:
75                         break;
76                 default:
77                         return -EINVAL;
78                 }
79                 return 0;
80         }
81
82         return -ENOTSUP;
83 }
84
85 static inline int
86 cnxk_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec_xform,
87                         struct rte_crypto_sym_xform *crypto_xform)
88 {
89         struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
90         int ret;
91
92         if ((ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
93             (ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_EGRESS))
94                 return -EINVAL;
95
96         if ((ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_ESP) &&
97             (ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_AH))
98                 return -EINVAL;
99
100         if ((ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) &&
101             (ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL))
102                 return -EINVAL;
103
104         if ((ipsec_xform->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) &&
105             (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV4) &&
106             (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV6))
107                 return -EINVAL;
108
109         if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
110                 return ipsec_xform_aead_verify(ipsec_xform, crypto_xform);
111
112         if (crypto_xform->next == NULL)
113                 return -EINVAL;
114
115         if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
116                 /* Ingress */
117                 if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
118                     crypto_xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
119                         return -EINVAL;
120                 auth_xform = crypto_xform;
121                 cipher_xform = crypto_xform->next;
122         } else {
123                 /* Egress */
124                 if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
125                     crypto_xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
126                         return -EINVAL;
127                 cipher_xform = crypto_xform;
128                 auth_xform = crypto_xform->next;
129         }
130
131         ret = ipsec_xform_cipher_verify(cipher_xform);
132         if (ret)
133                 return ret;
134
135         return ipsec_xform_auth_verify(auth_xform);
136 }
137 #endif /* __CNXK_IPSEC_H__ */