1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2020 Marvell International Ltd.
3  */
4 
5 #ifndef __OTX2_IPSEC_PO_H__
6 #define __OTX2_IPSEC_PO_H__
7 
8 #include <rte_crypto_sym.h>
9 #include <rte_ip.h>
10 #include <rte_security.h>
11 
12 #define OTX2_IPSEC_PO_AES_GCM_INB_CTX_LEN    0x09
13 #define OTX2_IPSEC_PO_AES_GCM_OUTB_CTX_LEN   0x28
14 
15 #define OTX2_IPSEC_PO_MAX_INB_CTX_LEN    0x22
16 #define OTX2_IPSEC_PO_MAX_OUTB_CTX_LEN   0x38
17 
18 #define OTX2_IPSEC_PO_PER_PKT_IV  BIT(11)
19 
20 #define OTX2_IPSEC_PO_WRITE_IPSEC_OUTB     0x20
21 #define OTX2_IPSEC_PO_WRITE_IPSEC_INB      0x21
22 #define OTX2_IPSEC_PO_PROCESS_IPSEC_OUTB   0x23
23 #define OTX2_IPSEC_PO_PROCESS_IPSEC_INB    0x24
24 
25 #define OTX2_IPSEC_PO_INB_RPTR_HDR         0x8
26 
27 enum otx2_ipsec_po_comp_e {
28 	OTX2_IPSEC_PO_CC_SUCCESS = 0x00,
29 	OTX2_IPSEC_PO_CC_AUTH_UNSUPPORTED = 0xB0,
30 	OTX2_IPSEC_PO_CC_ENCRYPT_UNSUPPORTED = 0xB1,
31 };
32 
33 enum {
34 	OTX2_IPSEC_PO_SA_DIRECTION_INBOUND = 0,
35 	OTX2_IPSEC_PO_SA_DIRECTION_OUTBOUND = 1,
36 };
37 
38 enum {
39 	OTX2_IPSEC_PO_SA_IP_VERSION_4 = 0,
40 	OTX2_IPSEC_PO_SA_IP_VERSION_6 = 1,
41 };
42 
43 enum {
44 	OTX2_IPSEC_PO_SA_MODE_TRANSPORT = 0,
45 	OTX2_IPSEC_PO_SA_MODE_TUNNEL = 1,
46 };
47 
48 enum {
49 	OTX2_IPSEC_PO_SA_PROTOCOL_AH = 0,
50 	OTX2_IPSEC_PO_SA_PROTOCOL_ESP = 1,
51 };
52 
53 enum {
54 	OTX2_IPSEC_PO_SA_AES_KEY_LEN_128 = 1,
55 	OTX2_IPSEC_PO_SA_AES_KEY_LEN_192 = 2,
56 	OTX2_IPSEC_PO_SA_AES_KEY_LEN_256 = 3,
57 };
58 
59 enum {
60 	OTX2_IPSEC_PO_SA_ENC_NULL = 0,
61 	OTX2_IPSEC_PO_SA_ENC_DES_CBC = 1,
62 	OTX2_IPSEC_PO_SA_ENC_3DES_CBC = 2,
63 	OTX2_IPSEC_PO_SA_ENC_AES_CBC = 3,
64 	OTX2_IPSEC_PO_SA_ENC_AES_CTR = 4,
65 	OTX2_IPSEC_PO_SA_ENC_AES_GCM = 5,
66 	OTX2_IPSEC_PO_SA_ENC_AES_CCM = 6,
67 };
68 
69 enum {
70 	OTX2_IPSEC_PO_SA_AUTH_NULL = 0,
71 	OTX2_IPSEC_PO_SA_AUTH_MD5 = 1,
72 	OTX2_IPSEC_PO_SA_AUTH_SHA1 = 2,
73 	OTX2_IPSEC_PO_SA_AUTH_SHA2_224 = 3,
74 	OTX2_IPSEC_PO_SA_AUTH_SHA2_256 = 4,
75 	OTX2_IPSEC_PO_SA_AUTH_SHA2_384 = 5,
76 	OTX2_IPSEC_PO_SA_AUTH_SHA2_512 = 6,
77 	OTX2_IPSEC_PO_SA_AUTH_AES_GMAC = 7,
78 	OTX2_IPSEC_PO_SA_AUTH_AES_XCBC_128 = 8,
79 };
80 
81 enum {
82 	OTX2_IPSEC_PO_SA_FRAG_POST = 0,
83 	OTX2_IPSEC_PO_SA_FRAG_PRE = 1,
84 };
85 
86 enum {
87 	OTX2_IPSEC_PO_SA_ENCAP_NONE = 0,
88 	OTX2_IPSEC_PO_SA_ENCAP_UDP = 1,
89 };
90 
91 struct otx2_ipsec_po_out_hdr {
92 	uint32_t ip_id;
93 	uint32_t seq;
94 	uint8_t iv[16];
95 };
96 
97 union otx2_ipsec_po_bit_perfect_iv {
98 	uint8_t aes_iv[16];
99 	uint8_t des_iv[8];
100 	struct {
101 		uint8_t nonce[4];
102 		uint8_t iv[8];
103 		uint8_t counter[4];
104 	} gcm;
105 };
106 
107 struct otx2_ipsec_po_traffic_selector {
108 	rte_be16_t src_port[2];
109 	rte_be16_t dst_port[2];
110 	RTE_STD_C11
111 	union {
112 		struct {
113 			rte_be32_t src_addr[2];
114 			rte_be32_t dst_addr[2];
115 		} ipv4;
116 		struct {
117 			uint8_t src_addr[32];
118 			uint8_t dst_addr[32];
119 		} ipv6;
120 	};
121 };
122 
123 struct otx2_ipsec_po_sa_ctl {
124 	rte_be32_t spi          : 32;
125 	uint64_t exp_proto_inter_frag : 8;
126 	uint64_t rsvd_42_40   : 3;
127 	uint64_t esn_en       : 1;
128 	uint64_t rsvd_45_44   : 2;
129 	uint64_t encap_type   : 2;
130 	uint64_t enc_type     : 3;
131 	uint64_t rsvd_48      : 1;
132 	uint64_t auth_type    : 4;
133 	uint64_t valid        : 1;
134 	uint64_t direction    : 1;
135 	uint64_t outer_ip_ver : 1;
136 	uint64_t inner_ip_ver : 1;
137 	uint64_t ipsec_mode   : 1;
138 	uint64_t ipsec_proto  : 1;
139 	uint64_t aes_key_len  : 2;
140 };
141 
142 struct otx2_ipsec_po_in_sa {
143 	/* w0 */
144 	struct otx2_ipsec_po_sa_ctl ctl;
145 
146 	/* w1-w4 */
147 	uint8_t cipher_key[32];
148 
149 	/* w5-w6 */
150 	union otx2_ipsec_po_bit_perfect_iv iv;
151 
152 	/* w7 */
153 	uint32_t esn_hi;
154 	uint32_t esn_low;
155 
156 	/* w8 */
157 	uint8_t udp_encap[8];
158 
159 	/* w9-w23 */
160 	struct {
161 		uint8_t hmac_key[48];
162 		struct otx2_ipsec_po_traffic_selector selector;
163 	} aes_gcm;
164 };
165 
166 struct otx2_ipsec_po_ip_template {
167 	RTE_STD_C11
168 	union {
169 		uint8_t raw[252];
170 		struct rte_ipv4_hdr ipv4_hdr;
171 		struct rte_ipv6_hdr ipv6_hdr;
172 	};
173 };
174 
175 struct otx2_ipsec_po_out_sa {
176 	/* w0 */
177 	struct otx2_ipsec_po_sa_ctl ctl;
178 
179 	/* w1-w4 */
180 	uint8_t cipher_key[32];
181 
182 	/* w5-w6 */
183 	union otx2_ipsec_po_bit_perfect_iv iv;
184 
185 	/* w7 */
186 	uint32_t esn_hi;
187 	uint32_t esn_low;
188 
189 	/* w8-w39 */
190 	struct otx2_ipsec_po_ip_template template;
191 	uint16_t udp_src;
192 	uint16_t udp_dst;
193 };
194 
195 static inline int
ipsec_po_xform_cipher_verify(struct rte_crypto_sym_xform * xform)196 ipsec_po_xform_cipher_verify(struct rte_crypto_sym_xform *xform)
197 {
198 	if (xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
199 		switch (xform->cipher.key.length) {
200 		case 16:
201 		case 24:
202 		case 32:
203 			break;
204 		default:
205 			return -ENOTSUP;
206 		}
207 		return 0;
208 	}
209 
210 	return -ENOTSUP;
211 }
212 
213 static inline int
ipsec_po_xform_auth_verify(struct rte_crypto_sym_xform * xform)214 ipsec_po_xform_auth_verify(struct rte_crypto_sym_xform *xform)
215 {
216 	uint16_t keylen = xform->auth.key.length;
217 
218 	if (xform->auth.algo == RTE_CRYPTO_AUTH_SHA1_HMAC) {
219 		if (keylen >= 20 && keylen <= 64)
220 			return 0;
221 	}
222 
223 	return -ENOTSUP;
224 }
225 
226 static inline int
ipsec_po_xform_aead_verify(struct rte_security_ipsec_xform * ipsec,struct rte_crypto_sym_xform * xform)227 ipsec_po_xform_aead_verify(struct rte_security_ipsec_xform *ipsec,
228 			   struct rte_crypto_sym_xform *xform)
229 {
230 	if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS &&
231 	    xform->aead.op != RTE_CRYPTO_AEAD_OP_ENCRYPT)
232 		return -EINVAL;
233 
234 	if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS &&
235 	    xform->aead.op != RTE_CRYPTO_AEAD_OP_DECRYPT)
236 		return -EINVAL;
237 
238 	if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
239 		switch (xform->aead.key.length) {
240 		case 16:
241 		case 24:
242 		case 32:
243 			break;
244 		default:
245 			return -EINVAL;
246 		}
247 		return 0;
248 	}
249 
250 	return -ENOTSUP;
251 }
252 
253 static inline int
ipsec_po_xform_verify(struct rte_security_ipsec_xform * ipsec,struct rte_crypto_sym_xform * xform)254 ipsec_po_xform_verify(struct rte_security_ipsec_xform *ipsec,
255 		      struct rte_crypto_sym_xform *xform)
256 {
257 	struct rte_crypto_sym_xform *auth_xform, *cipher_xform;
258 	int ret;
259 
260 	if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD)
261 		return ipsec_po_xform_aead_verify(ipsec, xform);
262 
263 	if (xform->next == NULL)
264 		return -EINVAL;
265 
266 	if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
267 		/* Ingress */
268 		if (xform->type != RTE_CRYPTO_SYM_XFORM_AUTH ||
269 		    xform->next->type != RTE_CRYPTO_SYM_XFORM_CIPHER)
270 			return -EINVAL;
271 		auth_xform = xform;
272 		cipher_xform = xform->next;
273 	} else {
274 		/* Egress */
275 		if (xform->type != RTE_CRYPTO_SYM_XFORM_CIPHER ||
276 		    xform->next->type != RTE_CRYPTO_SYM_XFORM_AUTH)
277 			return -EINVAL;
278 		cipher_xform = xform;
279 		auth_xform = xform->next;
280 	}
281 
282 	ret = ipsec_po_xform_cipher_verify(cipher_xform);
283 	if (ret)
284 		return ret;
285 
286 	ret = ipsec_po_xform_auth_verify(auth_xform);
287 	if (ret)
288 		return ret;
289 
290 	return 0;
291 }
292 
293 static inline int
ipsec_po_sa_ctl_set(struct rte_security_ipsec_xform * ipsec,struct rte_crypto_sym_xform * xform,struct otx2_ipsec_po_sa_ctl * ctl)294 ipsec_po_sa_ctl_set(struct rte_security_ipsec_xform *ipsec,
295 		    struct rte_crypto_sym_xform *xform,
296 		    struct otx2_ipsec_po_sa_ctl *ctl)
297 {
298 	struct rte_crypto_sym_xform *cipher_xform, *auth_xform;
299 	int aes_key_len;
300 
301 	if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_EGRESS) {
302 		ctl->direction = OTX2_IPSEC_PO_SA_DIRECTION_OUTBOUND;
303 		cipher_xform = xform;
304 		auth_xform = xform->next;
305 	} else if (ipsec->direction == RTE_SECURITY_IPSEC_SA_DIR_INGRESS) {
306 		ctl->direction = OTX2_IPSEC_PO_SA_DIRECTION_INBOUND;
307 		auth_xform = xform;
308 		cipher_xform = xform->next;
309 	} else {
310 		return -EINVAL;
311 	}
312 
313 	if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL) {
314 		if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV4)
315 			ctl->outer_ip_ver = OTX2_IPSEC_PO_SA_IP_VERSION_4;
316 		else if (ipsec->tunnel.type == RTE_SECURITY_IPSEC_TUNNEL_IPV6)
317 			ctl->outer_ip_ver = OTX2_IPSEC_PO_SA_IP_VERSION_6;
318 		else
319 			return -EINVAL;
320 	}
321 
322 	ctl->inner_ip_ver = ctl->outer_ip_ver;
323 
324 	if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TRANSPORT)
325 		ctl->ipsec_mode = OTX2_IPSEC_PO_SA_MODE_TRANSPORT;
326 	else if (ipsec->mode == RTE_SECURITY_IPSEC_SA_MODE_TUNNEL)
327 		ctl->ipsec_mode = OTX2_IPSEC_PO_SA_MODE_TUNNEL;
328 	else
329 		return -EINVAL;
330 
331 	if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_AH)
332 		ctl->ipsec_proto = OTX2_IPSEC_PO_SA_PROTOCOL_AH;
333 	else if (ipsec->proto == RTE_SECURITY_IPSEC_SA_PROTO_ESP)
334 		ctl->ipsec_proto = OTX2_IPSEC_PO_SA_PROTOCOL_ESP;
335 	else
336 		return -EINVAL;
337 
338 	if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
339 		if (xform->aead.algo == RTE_CRYPTO_AEAD_AES_GCM) {
340 			ctl->enc_type = OTX2_IPSEC_PO_SA_ENC_AES_GCM;
341 			aes_key_len = xform->aead.key.length;
342 		} else {
343 			return -ENOTSUP;
344 		}
345 	} else if (cipher_xform->cipher.algo == RTE_CRYPTO_CIPHER_AES_CBC) {
346 		ctl->enc_type = OTX2_IPSEC_PO_SA_ENC_AES_CCM;
347 		aes_key_len = xform->cipher.key.length;
348 	} else {
349 		return -ENOTSUP;
350 	}
351 
352 
353 	switch (aes_key_len) {
354 	case 16:
355 		ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_128;
356 		break;
357 	case 24:
358 		ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_192;
359 		break;
360 	case 32:
361 		ctl->aes_key_len = OTX2_IPSEC_PO_SA_AES_KEY_LEN_256;
362 		break;
363 	default:
364 		return -EINVAL;
365 	}
366 
367 	if (xform->type != RTE_CRYPTO_SYM_XFORM_AEAD) {
368 		switch (auth_xform->auth.algo) {
369 		case RTE_CRYPTO_AUTH_NULL:
370 			ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_NULL;
371 			break;
372 		case RTE_CRYPTO_AUTH_MD5_HMAC:
373 			ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_MD5;
374 			break;
375 		case RTE_CRYPTO_AUTH_SHA1_HMAC:
376 			ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA1;
377 			break;
378 		case RTE_CRYPTO_AUTH_SHA224_HMAC:
379 			ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_224;
380 			break;
381 		case RTE_CRYPTO_AUTH_SHA256_HMAC:
382 			ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_256;
383 			break;
384 		case RTE_CRYPTO_AUTH_SHA384_HMAC:
385 			ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_384;
386 			break;
387 		case RTE_CRYPTO_AUTH_SHA512_HMAC:
388 			ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_SHA2_512;
389 			break;
390 		case RTE_CRYPTO_AUTH_AES_GMAC:
391 			ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_AES_GMAC;
392 			break;
393 		case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
394 			ctl->auth_type = OTX2_IPSEC_PO_SA_AUTH_AES_XCBC_128;
395 			break;
396 		default:
397 			return -ENOTSUP;
398 		}
399 	}
400 
401 	if (ipsec->options.esn)
402 		ctl->esn_en = 1;
403 
404 	if (ipsec->options.udp_encap == 1)
405 		ctl->encap_type = OTX2_IPSEC_PO_SA_ENCAP_UDP;
406 
407 	ctl->spi = rte_cpu_to_be_32(ipsec->spi);
408 	ctl->valid = 1;
409 
410 	return 0;
411 }
412 
413 #endif /* __OTX2_IPSEC_PO_H__ */
414