1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2020 Marvell International Ltd.
3  */
4 
5 #ifndef __OTX2_IPSEC_FP_H__
6 #define __OTX2_IPSEC_FP_H__
7 
8 #include <rte_crypto_sym.h>
9 #include <rte_security.h>
10 
11 /* Macros for anti replay and ESN */
12 #define OTX2_IPSEC_MAX_REPLAY_WIN_SZ	1024
13 #define OTX2_IPSEC_SAINDEX_SZ		4
14 #define OTX2_IPSEC_SEQNO_LO		4
15 
16 #define OTX2_IPSEC_SEQNO_LO_INDEX	(RTE_ETHER_HDR_LEN + \
17 					 OTX2_IPSEC_SAINDEX_SZ)
18 
19 #define OTX2_IPSEC_SEQNO_HI_INDEX	(OTX2_IPSEC_SEQNO_LO_INDEX + \
20 					 OTX2_IPSEC_SEQNO_LO)
21 
22 enum {
23 	OTX2_IPSEC_FP_SA_DIRECTION_INBOUND = 0,
24 	OTX2_IPSEC_FP_SA_DIRECTION_OUTBOUND = 1,
25 };
26 
27 enum {
28 	OTX2_IPSEC_FP_SA_IP_VERSION_4 = 0,
29 	OTX2_IPSEC_FP_SA_IP_VERSION_6 = 1,
30 };
31 
32 enum {
33 	OTX2_IPSEC_FP_SA_MODE_TRANSPORT = 0,
34 	OTX2_IPSEC_FP_SA_MODE_TUNNEL = 1,
35 };
36 
37 enum {
38 	OTX2_IPSEC_FP_SA_PROTOCOL_AH = 0,
39 	OTX2_IPSEC_FP_SA_PROTOCOL_ESP = 1,
40 };
41 
42 enum {
43 	OTX2_IPSEC_FP_SA_AES_KEY_LEN_128 = 1,
44 	OTX2_IPSEC_FP_SA_AES_KEY_LEN_192 = 2,
45 	OTX2_IPSEC_FP_SA_AES_KEY_LEN_256 = 3,
46 };
47 
48 enum {
49 	OTX2_IPSEC_FP_SA_ENC_NULL = 0,
50 	OTX2_IPSEC_FP_SA_ENC_DES_CBC = 1,
51 	OTX2_IPSEC_FP_SA_ENC_3DES_CBC = 2,
52 	OTX2_IPSEC_FP_SA_ENC_AES_CBC = 3,
53 	OTX2_IPSEC_FP_SA_ENC_AES_CTR = 4,
54 	OTX2_IPSEC_FP_SA_ENC_AES_GCM = 5,
55 	OTX2_IPSEC_FP_SA_ENC_AES_CCM = 6,
56 };
57 
58 enum {
59 	OTX2_IPSEC_FP_SA_AUTH_NULL = 0,
60 	OTX2_IPSEC_FP_SA_AUTH_MD5 = 1,
61 	OTX2_IPSEC_FP_SA_AUTH_SHA1 = 2,
62 	OTX2_IPSEC_FP_SA_AUTH_SHA2_224 = 3,
63 	OTX2_IPSEC_FP_SA_AUTH_SHA2_256 = 4,
64 	OTX2_IPSEC_FP_SA_AUTH_SHA2_384 = 5,
65 	OTX2_IPSEC_FP_SA_AUTH_SHA2_512 = 6,
66 	OTX2_IPSEC_FP_SA_AUTH_AES_GMAC = 7,
67 	OTX2_IPSEC_FP_SA_AUTH_AES_XCBC_128 = 8,
68 };
69 
70 enum {
71 	OTX2_IPSEC_FP_SA_FRAG_POST = 0,
72 	OTX2_IPSEC_FP_SA_FRAG_PRE = 1,
73 };
74 
75 enum {
76 	OTX2_IPSEC_FP_SA_ENCAP_NONE = 0,
77 	OTX2_IPSEC_FP_SA_ENCAP_UDP = 1,
78 };
79 
80 struct otx2_ipsec_fp_sa_ctl {
81 	rte_be32_t spi          : 32;
82 	uint64_t exp_proto_inter_frag : 8;
83 	uint64_t rsvd_42_40   : 3;
84 	uint64_t esn_en       : 1;
85 	uint64_t rsvd_45_44   : 2;
86 	uint64_t encap_type   : 2;
87 	uint64_t enc_type     : 3;
88 	uint64_t rsvd_48      : 1;
89 	uint64_t auth_type    : 4;
90 	uint64_t valid        : 1;
91 	uint64_t direction    : 1;
92 	uint64_t outer_ip_ver : 1;
93 	uint64_t inner_ip_ver : 1;
94 	uint64_t ipsec_mode   : 1;
95 	uint64_t ipsec_proto  : 1;
96 	uint64_t aes_key_len  : 2;
97 };
98 
99 struct otx2_ipsec_fp_out_sa {
100 	/* w0 */
101 	struct otx2_ipsec_fp_sa_ctl ctl;
102 
103 	/* w1 */
104 	uint8_t nonce[4];
105 	uint16_t udp_src;
106 	uint16_t udp_dst;
107 
108 	/* w2 */
109 	uint32_t ip_src;
110 	uint32_t ip_dst;
111 
112 	/* w3-w6 */
113 	uint8_t cipher_key[32];
114 
115 	/* w7-w12 */
116 	uint8_t hmac_key[48];
117 };
118 
119 struct otx2_ipsec_replay {
120 	rte_spinlock_t lock;
121 	uint32_t winb;
122 	uint32_t wint;
123 	uint64_t base; /**< base of the anti-replay window */
124 	uint64_t window[17]; /**< anti-replay window */
125 };
126 
127 struct otx2_ipsec_fp_in_sa {
128 	/* w0 */
129 	struct otx2_ipsec_fp_sa_ctl ctl;
130 
131 	/* w1 */
132 	uint8_t nonce[4]; /* Only for AES-GCM */
133 	uint32_t unused;
134 
135 	/* w2 */
136 	uint32_t esn_hi;
137 	uint32_t esn_low;
138 
139 	/* w3-w6 */
140 	uint8_t cipher_key[32];
141 
142 	/* w7-w12 */
143 	uint8_t hmac_key[48];
144 
145 	RTE_STD_C11
146 	union {
147 		void *userdata;
148 		uint64_t udata64;
149 	};
150 	union {
151 		struct otx2_ipsec_replay *replay;
152 		uint64_t replay64;
153 	};
154 	uint32_t replay_win_sz;
155 
156 	uint32_t reserved1;
157 };
158 
159 static inline int
ipsec_fp_xform_cipher_verify(struct rte_crypto_sym_xform * xform)160 ipsec_fp_xform_cipher_verify(struct rte_crypto_sym_xform *xform)
161 {
162 	if (xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
163 		switch (xform->cipher.key.length) {
164 		case 16:
165 		case 24:
166 		case 32:
167 			break;
168 		default:
169 			return -ENOTSUP;
170 		}
171 		return 0;
172 	}
173 
174 	return -ENOTSUP;
175 }
176 
177 static inline int
ipsec_fp_xform_auth_verify(struct rte_crypto_sym_xform * xform)178 ipsec_fp_xform_auth_verify(struct rte_crypto_sym_xform *xform)
179 {
180 	uint16_t keylen = xform->auth.key.length;
181 
182 	if (xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) {
183 		if (keylen >= 20 && keylen <= 64)
184 			return 0;
185 	}
186 
187 	return -ENOTSUP;
188 }
189 
190 static inline int
ipsec_fp_xform_aead_verify(struct rte_security_ipsec_xform * ipsec,struct rte_crypto_sym_xform * xform)191 ipsec_fp_xform_aead_verify(struct rte_security_ipsec_xform *ipsec,
192 			   struct rte_crypto_sym_xform *xform)
193 {
194 	if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
195 	    xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
196 		return -EINVAL;
197 
198 	if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
199 	    xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
200 		return -EINVAL;
201 
202 	if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
203 		switch (xform->aead.key.length) {
204 		case 16:
205 		case 24:
206 		case 32:
207 			break;
208 		default:
209 			return -EINVAL;
210 		}
211 		return 0;
212 	}
213 
214 	return -ENOTSUP;
215 }
216 
217 static inline int
ipsec_fp_xform_verify(struct rte_security_ipsec_xform * ipsec,struct rte_crypto_sym_xform * xform)218 ipsec_fp_xform_verify(struct rte_security_ipsec_xform *ipsec,
219 		      struct rte_crypto_sym_xform *xform)
220 {
221 	struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
222 	int ret;
223 
224 	if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
225 		return ipsec_fp_xform_aead_verify(ipsec, xform);
226 
227 	if (xform->next == NULL)
228 		return -EINVAL;
229 
230 	if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
231 		/* Ingress */
232 		if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
233 		    xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
234 			return -EINVAL;
235 		auth_xform = xform;
236 		cipher_xform = xform->next;
237 	} else {
238 		/* Egress */
239 		if (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
240 		    xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
241 			return -EINVAL;
242 		cipher_xform = xform;
243 		auth_xform = xform->next;
244 	}
245 
246 	ret = ipsec_fp_xform_cipher_verify(cipher_xform);
247 	if (ret)
248 		return ret;
249 
250 	ret = ipsec_fp_xform_auth_verify(auth_xform);
251 	if (ret)
252 		return ret;
253 
254 	return 0;
255 }
256 
257 static inline int
ipsec_fp_sa_ctl_set(struct rte_security_ipsec_xform * ipsec,struct rte_crypto_sym_xform * xform,struct otx2_ipsec_fp_sa_ctl * ctl)258 ipsec_fp_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
259 		    struct rte_crypto_sym_xform *xform,
260 		    struct otx2_ipsec_fp_sa_ctl *ctl)
261 {
262 	struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
263 	int aes_key_len;
264 
265 	if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
266 		ctl->direction = OTX2_IPSEC_FP_SA_DIRECTION_OUTBOUND;
267 		cipher_xform = xform;
268 		auth_xform = xform->next;
269 	} else if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
270 		ctl->direction = OTX2_IPSEC_FP_SA_DIRECTION_INBOUND;
271 		auth_xform = xform;
272 		cipher_xform = xform->next;
273 	} else {
274 		return -EINVAL;
275 	}
276 
277 	if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
278 		if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
279 			ctl->outer_ip_ver = OTX2_IPSEC_FP_SA_IP_VERSION_4;
280 		else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
281 			ctl->outer_ip_ver = OTX2_IPSEC_FP_SA_IP_VERSION_6;
282 		else
283 			return -EINVAL;
284 	}
285 
286 	ctl->inner_ip_ver = OTX2_IPSEC_FP_SA_IP_VERSION_4;
287 
288 	if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT)
289 		ctl->ipsec_mode = OTX2_IPSEC_FP_SA_MODE_TRANSPORT;
290 	else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
291 		ctl->ipsec_mode = OTX2_IPSEC_FP_SA_MODE_TUNNEL;
292 	else
293 		return -EINVAL;
294 
295 	if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
296 		ctl->ipsec_proto = OTX2_IPSEC_FP_SA_PROTOCOL_AH;
297 	else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP)
298 		ctl->ipsec_proto = OTX2_IPSEC_FP_SA_PROTOCOL_ESP;
299 	else
300 		return -EINVAL;
301 
302 	if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
303 		if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
304 			ctl->enc_type = OTX2_IPSEC_FP_SA_ENC_AES_GCM;
305 			aes_key_len = xform->aead.key.length;
306 		} else {
307 			return -ENOTSUP;
308 		}
309 	} else if (cipher_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
310 		ctl->enc_type = OTX2_IPSEC_FP_SA_ENC_AES_CBC;
311 		aes_key_len = cipher_xform->cipher.key.length;
312 	} else {
313 		return -ENOTSUP;
314 	}
315 
316 	switch (aes_key_len) {
317 	case 16:
318 		ctl->aes_key_len = OTX2_IPSEC_FP_SA_AES_KEY_LEN_128;
319 		break;
320 	case 24:
321 		ctl->aes_key_len = OTX2_IPSEC_FP_SA_AES_KEY_LEN_192;
322 		break;
323 	case 32:
324 		ctl->aes_key_len = OTX2_IPSEC_FP_SA_AES_KEY_LEN_256;
325 		break;
326 	default:
327 		return -EINVAL;
328 	}
329 
330 	if (xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
331 		switch (auth_xform->auth.algo) {
332 		case RTE_CRYPTO_AUTH_NULL:
333 			ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_NULL;
334 			break;
335 		case RTE_CRYPTO_AUTH_MD5_HMAC:
336 			ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_MD5;
337 			break;
338 		case RTE_CRYPTO_AUTH_SHA1_HMAC:
339 			ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_SHA1;
340 			break;
341 		case RTE_CRYPTO_AUTH_SHA224_HMAC:
342 			ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_SHA2_224;
343 			break;
344 		case RTE_CRYPTO_AUTH_SHA256_HMAC:
345 			ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_SHA2_256;
346 			break;
347 		case RTE_CRYPTO_AUTH_SHA384_HMAC:
348 			ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_SHA2_384;
349 			break;
350 		case RTE_CRYPTO_AUTH_SHA512_HMAC:
351 			ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_SHA2_512;
352 			break;
353 		case RTE_CRYPTO_AUTH_AES_GMAC:
354 			ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_AES_GMAC;
355 			break;
356 		case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
357 			ctl->auth_type = OTX2_IPSEC_FP_SA_AUTH_AES_XCBC_128;
358 			break;
359 		default:
360 			return -ENOTSUP;
361 		}
362 	}
363 
364 	if (ipsec->options.esn == 1)
365 		ctl->esn_en = 1;
366 
367 	ctl->spi = rte_cpu_to_be_32(ipsec->spi);
368 	ctl->valid = 1;
369 
370 	return 0;
371 }
372 
373 #endif /* __OTX2_IPSEC_FP_H__ */
374