xref: /dpdk/drivers/crypto/cnxk/cnxk_ipsec.h (revision e85982ab)
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
ipsec_xform_cipher_verify(struct rte_crypto_sym_xform * crypto_xform)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
ipsec_xform_auth_verify(struct rte_crypto_sym_xform * crypto_xform)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 	} else if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_AES_GMAC) {
63 		if (keylen >= 16 && keylen <= 32)
64 			return 0;
65 	}
66 
67 	if (crypto_xform->auth.algo == RTE_CRYPTO_AUTH_AES_XCBC_MAC &&
68 	    keylen == ROC_CPT_AES_XCBC_KEY_LENGTH)
69 		return 0;
70 
71 	return -ENOTSUP;
72 }
73 
74 static inline int
ipsec_xform_aead_verify(struct rte_security_ipsec_xform * ipsec_xform,struct rte_crypto_sym_xform * crypto_xform)75 ipsec_xform_aead_verify(struct rte_security_ipsec_xform *ipsec_xform,
76 			struct rte_crypto_sym_xform *crypto_xform)
77 {
78 	if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
79 	    crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
80 		return -EINVAL;
81 
82 	if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
83 	    crypto_xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
84 		return -EINVAL;
85 
86 	if (crypto_xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
87 		switch (crypto_xform->aead.key.length) {
88 		case 16:
89 		case 24:
90 		case 32:
91 			break;
92 		default:
93 			return -EINVAL;
94 		}
95 		return 0;
96 	}
97 
98 	return -ENOTSUP;
99 }
100 
101 static inline int
cnxk_ipsec_xform_verify(struct rte_security_ipsec_xform * ipsec_xform,struct rte_crypto_sym_xform * crypto_xform)102 cnxk_ipsec_xform_verify(struct rte_security_ipsec_xform *ipsec_xform,
103 			struct rte_crypto_sym_xform *crypto_xform)
104 {
105 	struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
106 	int ret;
107 
108 	if ((ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_INGRESS) &&
109 	    (ipsec_xform->direction != RTE_SECURITY_IPSEC_SA_DIR_EGRESS))
110 		return -EINVAL;
111 
112 	if ((ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_ESP) &&
113 	    (ipsec_xform->proto != RTE_SECURITY_IPSEC_SA_PROTO_AH))
114 		return -EINVAL;
115 
116 	if ((ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT) &&
117 	    (ipsec_xform->mode != RTE_SECURITY_IPSEC_SA_MODE_TUNNEL))
118 		return -EINVAL;
119 
120 	if ((ipsec_xform->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) &&
121 	    (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV4) &&
122 	    (ipsec_xform->tunnel.type != RTE_SECURITY_IPSEC_TUNNEL_IPV6))
123 		return -EINVAL;
124 
125 	if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
126 		return ipsec_xform_aead_verify(ipsec_xform, crypto_xform);
127 
128 	if (ipsec_xform->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH) {
129 		if (ipsec_xform->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
130 			/* Ingress */
131 			auth_xform = crypto_xform;
132 			cipher_xform = crypto_xform->next;
133 
134 			if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH)
135 				return -EINVAL;
136 
137 			if ((cipher_xform != NULL) && ((cipher_xform->type !=
138 			    RTE_CRYPTO_SYM_XFORM_CIPHER) ||
139 			    (cipher_xform->cipher.algo !=
140 			    RTE_CRYPTO_CIPHER_NULL)))
141 				return -EINVAL;
142 		} else {
143 				/* Egress */
144 			if (crypto_xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
145 				cipher_xform = crypto_xform;
146 				auth_xform = crypto_xform->next;
147 
148 				if (auth_xform == NULL ||
149 				    cipher_xform->cipher.algo !=
150 				    RTE_CRYPTO_CIPHER_NULL)
151 					return -EINVAL;
152 			} else if (crypto_xform->type ==
153 				   RTE_CRYPTO_SYM_XFORM_AUTH)
154 				auth_xform = crypto_xform;
155 			else
156 				return -EINVAL;
157 		}
158 	} else {
159 		if (crypto_xform->next == NULL)
160 			return -EINVAL;
161 
162 		if (ipsec_xform->direction ==
163 		    RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
164 			/* Ingress */
165 			if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
166 			    crypto_xform->next->type !=
167 				    RTE_CRYPTO_SYM_XFORM_CIPHER)
168 				return -EINVAL;
169 			auth_xform = crypto_xform;
170 			cipher_xform = crypto_xform->next;
171 		} else {
172 			/* Egress */
173 			if (crypto_xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
174 			    crypto_xform->next->type !=
175 				    RTE_CRYPTO_SYM_XFORM_AUTH)
176 				return -EINVAL;
177 			cipher_xform = crypto_xform;
178 			auth_xform = crypto_xform->next;
179 		}
180 
181 		ret = ipsec_xform_cipher_verify(cipher_xform);
182 		if (ret)
183 			return ret;
184 	}
185 
186 	return ipsec_xform_auth_verify(auth_xform);
187 }
188 #endif /* __CNXK_IPSEC_H__ */
189