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