xref: /dpdk/drivers/crypto/cnxk/cnxk_ipsec.h (revision fdbec406b550d703f1de76a3a719db67d05afde4)
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_cpt.h"
11 #include "roc_ie_on.h"
12 #include "roc_ie_ot.h"
13 
14 extern struct rte_security_ops cnxk_sec_ops;
15 
16 struct cnxk_cpt_inst_tmpl {
17 	uint64_t w2;
18 	uint64_t w4;
19 	uint64_t w7;
20 };
21 
22 static inline int
ipsec_xform_cipher_verify(struct rte_crypto_sym_xform * crypto_xform)23 ipsec_xform_cipher_verify(struct rte_crypto_sym_xform *crypto_xform)
24 {
25 	if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_NULL)
26 		return 0;
27 
28 	if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_DES_CBC &&
29 	    crypto_xform->cipher.key.length == 8)
30 		return 0;
31 
32 	if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC ||
33 	    crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CTR) {
34 		switch (crypto_xform->cipher.key.length) {
35 		case 16:
36 		case 24:
37 		case 32:
38 			break;
39 		default:
40 			return -ENOTSUP;
41 		}
42 		return 0;
43 	}
44 
45 	if (crypto_xform->cipher.algo == RTE_CRYPTO_CIPHER_3DES_CBC &&
46 	    crypto_xform->cipher.key.length == 24)
47 		return 0;
48 
49 	return -ENOTSUP;
50 }
51 
52 static inline int
ipsec_xform_auth_verify(struct rte_crypto_sym_xform * crypto_xform)53 ipsec_xform_auth_verify(struct rte_crypto_sym_xform *crypto_xform)
54 {
55 	uint16_t keylen = crypto_xform->auth.key.length;
56 
57 	if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_NULL)
58 		return 0;
59 
60 	if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_MD5_HMAC) {
61 		if (keylen == 16)
62 			return 0;
63 	}
64 
65 	if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) {
66 		if (keylen >= 20 && keylen <= 64)
67 			return 0;
68 	} else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA256_HMAC) {
69 		if (keylen >= 32 && keylen <= 64)
70 			return 0;
71 	} else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA384_HMAC) {
72 		if (keylen == 48)
73 			return 0;
74 	} else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_SHA512_HMAC) {
75 		if (keylen == 64)
76 			return 0;
77 	} else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
78 		if (keylen >= 16 && keylen <= 32)
79 			return 0;
80 	}
81 
82 	if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC &&
83 	    keylen == ROC_CPT_AES_XCBC_KEY_LENGTH)
84 		return 0;
85 
86 	return -ENOTSUP;
87 }
88 
89 static inline int
ipsec_xform_aead_verify(struct rte_security_ipsec_xform * ipsec_xform,struct rte_crypto_sym_xform * crypto_xform)90 ipsec_xform_aead_verify(struct rte_security_ipsec_xform *ipsec_xform,
91 			struct rte_crypto_sym_xform *crypto_xform)
92 {
93 	if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
94 	    crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
95 		return -EINVAL;
96 
97 	if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
98 	    crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
99 		return -EINVAL;
100 
101 	if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM ||
102 	    crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_CCM) {
103 		switch (crypto_xform->aead.key.length) {
104 		case 16:
105 		case 24:
106 		case 32:
107 			break;
108 		default:
109 			return -EINVAL;
110 		}
111 		return 0;
112 	}
113 
114 	return -ENOTSUP;
115 }
116 
117 static inline int
cnxk_ipsec_xform_verify(struct rte_security_ipsec_xform * ipsec_xform,struct rte_crypto_sym_xform * crypto_xform)118 cnxk_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec_xform,
119 			struct rte_crypto_sym_xform *crypto_xform)
120 {
121 	struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
122 	int ret;
123 
124 	if ((ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
125 	    (ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_EGRESS))
126 		return -EINVAL;
127 
128 	if ((ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_ESP) &&
129 	    (ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_AH))
130 		return -EINVAL;
131 
132 	if ((ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) &&
133 	    (ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL))
134 		return -EINVAL;
135 
136 	if ((ipsec_xform->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) &&
137 	    (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV4) &&
138 	    (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV6))
139 		return -EINVAL;
140 
141 	if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
142 		return ipsec_xform_aead_verify(ipsec_xform, crypto_xform);
143 
144 	if (ipsec_xform->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) {
145 		if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
146 			/* Ingress */
147 			auth_xform = crypto_xform;
148 			cipher_xform = crypto_xform->next;
149 
150 			if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH)
151 				return -EINVAL;
152 
153 			if ((cipher_xform != NULL) && ((cipher_xform->type !=
154 			    RTE_CRYPTO_SYM_XFORM_CIPHER) ||
155 			    (cipher_xform->cipher.algo !=
156 			    RTE_CRYPTO_CIPHER_NULL)))
157 				return -EINVAL;
158 		} else {
159 				/* Egress */
160 			if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
161 				cipher_xform = crypto_xform;
162 				auth_xform = crypto_xform->next;
163 
164 				if (auth_xform == NULL ||
165 				    cipher_xform->cipher.algo !=
166 				    RTE_CRYPTO_CIPHER_NULL)
167 					return -EINVAL;
168 			} else if (crypto_xform->type ==
169 				   RTE_CRYPTO_SYM_XFORM_AUTH)
170 				auth_xform = crypto_xform;
171 			else
172 				return -EINVAL;
173 		}
174 	} else {
175 		if (crypto_xform->next == NULL)
176 			return -EINVAL;
177 
178 		if (ipsec_xform->direction ==
179 		    RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
180 			/* Ingress */
181 			if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
182 			    crypto_xform->next->type !=
183 				    RTE_CRYPTO_SYM_XFORM_CIPHER)
184 				return -EINVAL;
185 			auth_xform = crypto_xform;
186 			cipher_xform = crypto_xform->next;
187 		} else {
188 			/* Egress */
189 			if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
190 			    crypto_xform->next->type !=
191 				    RTE_CRYPTO_SYM_XFORM_AUTH)
192 				return -EINVAL;
193 			cipher_xform = crypto_xform;
194 			auth_xform = crypto_xform->next;
195 		}
196 
197 		ret = ipsec_xform_cipher_verify(cipher_xform);
198 		if (ret)
199 			return ret;
200 	}
201 
202 	return ipsec_xform_auth_verify(auth_xform);
203 }
204 #endif /* __CNXK_IPSEC_H__ */
205