xref: /dpdk/drivers/common/dpaax/caamflib/desc/ipsec.h (revision 046341575bd6e1210d6c12b595405ede41150da7)
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2008-2016 Freescale Semiconductor Inc.
4  * Copyright 2016,2019-2022 NXP
5  *
6  */
7 
8 #ifndef __DESC_IPSEC_H__
9 #define __DESC_IPSEC_H__
10 
11 #include "rta.h"
12 #include "common.h"
13 
14 /**
15  * DOC: IPsec Shared Descriptor Constructors
16  *
17  * Shared descriptors for IPsec protocol.
18  */
19 
20 /* General IPSec ESP encap / decap PDB options */
21 
22 /**
23  * PDBOPTS_ESP_ESN - Extended sequence included
24  */
25 #define PDBOPTS_ESP_ESN		0x10
26 
27 /**
28  * PDBOPTS_ESP_IPVSN - Process IPv6 header
29  *
30  * Valid only for IPsec legacy mode.
31  */
32 #define PDBOPTS_ESP_IPVSN	0x02
33 
34 /**
35  * PDBOPTS_ESP_TUNNEL - Tunnel mode next-header byte
36  *
37  * Valid only for IPsec legacy mode.
38  */
39 #define PDBOPTS_ESP_TUNNEL	0x01
40 
41 /* IPSec ESP Encap PDB options */
42 
43 /**
44  * PDBOPTS_ESP_UPDATE_CSUM - Update ip header checksum
45  *
46  * Valid only for IPsec legacy mode.
47  */
48 #define PDBOPTS_ESP_UPDATE_CSUM 0x80
49 
50 /**
51  * PDBOPTS_ESP_DIFFSERV - Copy TOS/TC from inner iphdr
52  *
53  * Valid only for IPsec legacy mode.
54  */
55 #define PDBOPTS_ESP_DIFFSERV	0x40
56 
57 /**
58  * PDBOPTS_ESP_IVSRC - IV comes from internal random gen
59  */
60 #define PDBOPTS_ESP_IVSRC	0x20
61 
62 /**
63  * PDBOPTS_ESP_IPHDRSRC - IP header comes from PDB
64  *
65  * Valid only for IPsec legacy mode.
66  */
67 #define PDBOPTS_ESP_IPHDRSRC	0x08
68 
69 /**
70  * PDBOPTS_ESP_INCIPHDR - Prepend IP header to output frame
71  *
72  * Valid only for IPsec legacy mode.
73  */
74 #define PDBOPTS_ESP_INCIPHDR	0x04
75 
76 /**
77  * PDBOPTS_ESP_OIHI_MASK - Mask for Outer IP Header Included
78  *
79  * Valid only for IPsec new mode.
80  */
81 #define PDBOPTS_ESP_OIHI_MASK	0x0c
82 
83 /**
84  * PDBOPTS_ESP_OIHI_PDB_INL - Prepend IP header to output frame from PDB (where
85  *                            it is inlined).
86  *
87  * Valid only for IPsec new mode.
88  */
89 #define PDBOPTS_ESP_OIHI_PDB_INL 0x0c
90 
91 /**
92  * PDBOPTS_ESP_OIHI_PDB_REF - Prepend IP header to output frame from PDB
93  *                            (referenced by pointer).
94  *
95  * Vlid only for IPsec new mode.
96  */
97 #define PDBOPTS_ESP_OIHI_PDB_REF 0x08
98 
99 /**
100  * PDBOPTS_ESP_OIHI_IF - Prepend IP header to output frame from input frame
101  *
102  * Valid only for IPsec new mode.
103  */
104 #define PDBOPTS_ESP_OIHI_IF	0x04
105 
106 /**
107  * PDBOPTS_ESP_NAT - Enable RFC 3948 UDP-encapsulated-ESP
108  *
109  * Valid only for IPsec new mode.
110  */
111 #define PDBOPTS_ESP_NAT		0x02
112 
113 /**
114  * PDBOPTS_ESP_NUC - Enable NAT UDP Checksum
115  *
116  * Valid only for IPsec new mode.
117  */
118 #define PDBOPTS_ESP_NUC		0x01
119 
120 /* IPSec ESP Decap PDB options */
121 
122 /**
123  * PDBOPTS_ESP_ARS_MASK_ERA10 - antireplay window mask
124  * for SEC_ERA >= 10
125  */
126 #define PDBOPTS_ESP_ARS_MASK_ERA10	0xc8
127 
128 /**
129  * PDBOPTS_ESP_ARS_MASK - antireplay window mask
130  * for SEC_ERA < 10
131  */
132 #define PDBOPTS_ESP_ARS_MASK	0xc0
133 
134 /**
135  * PDBOPTS_ESP_ARSNONE - No antireplay window
136  */
137 #define PDBOPTS_ESP_ARSNONE	0x00
138 
139 /**
140  * PDBOPTS_ESP_ARS64 - 64-entry antireplay window
141  */
142 #define PDBOPTS_ESP_ARS64	0xc0
143 
144 /**
145  * PDBOPTS_ESP_ARS128 - 128-entry antireplay window
146  *
147  * Valid only for IPsec new mode.
148  */
149 #define PDBOPTS_ESP_ARS128	0x80
150 
151 /**
152  * PDBOPTS_ESP_ARS256 - 256-entry antireplay window
153  *
154  * Valid only for IPsec new mode.
155  */
156 #define PDBOPTS_ESP_ARS256	0x08
157 
158 /**
159  * PDBOPTS_ESP_ARS512 - 512-entry antireplay window
160  *
161  * Valid only for IPsec new mode.
162  */
163 #define PDBOPTS_ESP_ARS512	0x48
164 
165 /**
166  * PDBOPTS_ESP_ARS1024 - 1024-entry antireplay window
167  *
168  * Valid only for IPsec new mode.
169  */
170 #define PDBOPTS_ESP_ARS1024	0x88
171 
172 /**
173  * PDBOPTS_ESP_ARS32 - 32-entry antireplay window
174  */
175 #define PDBOPTS_ESP_ARS32	0x40
176 
177 /**
178  * PDBOPTS_ESP_VERIFY_CSUM - Validate ip header checksum
179  *
180  * Valid only for IPsec legacy mode.
181  */
182 #define PDBOPTS_ESP_VERIFY_CSUM 0x20
183 
184 /**
185  * PDBOPTS_ESP_TECN - Implement RRFC6040 ECN tunneling from outer header to
186  *                    inner header.
187  *
188  * Valid only for IPsec new mode.
189  */
190 #define PDBOPTS_ESP_TECN	0x20
191 
192 /**
193  * PDBOPTS_ESP_OUTFMT - Output only decapsulation
194  *
195  * Valid only for IPsec legacy mode.
196  */
197 #define PDBOPTS_ESP_OUTFMT	0x08
198 
199 /**
200  * PDBOPTS_ESP_AOFL - Adjust out frame len
201  *
202  * Valid only for IPsec legacy mode and for SEC >= 5.3.
203  */
204 #define PDBOPTS_ESP_AOFL	0x04
205 
206 /**
207  * PDBOPTS_ESP_ETU - EtherType Update
208  *
209  * Add corresponding ethertype (0x0800 for IPv4, 0x86dd for IPv6) in the output
210  * frame.
211  * Valid only for IPsec new mode.
212  */
213 #define PDBOPTS_ESP_ETU		0x01
214 
215 #define PDBHMO_ESP_DECAP_SHIFT		28
216 #define PDBHMO_ESP_ENCAP_SHIFT		28
217 #define PDBNH_ESP_ENCAP_SHIFT		16
218 #define PDBNH_ESP_ENCAP_MASK		(0xff << PDBNH_ESP_ENCAP_SHIFT)
219 #define PDBHDRLEN_ESP_DECAP_SHIFT	16
220 #define PDBHDRLEN_MASK			(0x0fff << PDBHDRLEN_ESP_DECAP_SHIFT)
221 #define PDB_NH_OFFSET_SHIFT		8
222 #define PDB_NH_OFFSET_MASK		(0xff << PDB_NH_OFFSET_SHIFT)
223 
224 /**
225  * PDBHMO_ESP_DECAP_DTTL - IPsec ESP decrement TTL (IPv4) / Hop limit (IPv6)
226  *                         HMO option.
227  */
228 #define PDBHMO_ESP_DECAP_DTTL	(0x02 << PDBHMO_ESP_DECAP_SHIFT)
229 
230 /**
231  * PDBHMO_ESP_ENCAP_DTTL - IPsec ESP increment TTL (IPv4) / Hop limit (IPv6)
232  *                         HMO option.
233  */
234 #define PDBHMO_ESP_ENCAP_DTTL	(0x02 << PDBHMO_ESP_ENCAP_SHIFT)
235 
236 /**
237  * PDBHMO_ESP_DIFFSERV - (Decap) DiffServ Copy - Copy the IPv4 TOS or IPv6
238  *                       Traffic Class byte from the outer IP header to the
239  *                       inner IP header.
240  */
241 #define PDBHMO_ESP_DIFFSERV	(0x01 << PDBHMO_ESP_DECAP_SHIFT)
242 
243 /**
244  * PDBHMO_ESP_SNR - (Encap) - Sequence Number Rollover control
245  *
246  * Configures behaviour in case of SN / ESN rollover:
247  * error if SNR = 1, rollover allowed if SNR = 0.
248  * Valid only for IPsec new mode.
249  */
250 #define PDBHMO_ESP_SNR		(0x01 << PDBHMO_ESP_ENCAP_SHIFT)
251 
252 /**
253  * PDBHMO_ESP_DFBIT - (Encap) Copy DF bit - if an IPv4 tunnel mode outer IP
254  *                    header is coming from the PDB, copy the DF bit from the
255  *                    inner IP header to the outer IP header.
256  */
257 #define PDBHMO_ESP_DFBIT	(0x04 << PDBHMO_ESP_ENCAP_SHIFT)
258 
259 /**
260  * PDBHMO_ESP_DFV - (Decap) - DF bit value
261  *
262  * If ODF = 1, DF bit in output frame is replaced by DFV.
263  * Valid only from SEC Era 5 onwards.
264  */
265 #define PDBHMO_ESP_DFV		(0x04 << PDBHMO_ESP_DECAP_SHIFT)
266 
267 /**
268  * PDBHMO_ESP_ODF - (Decap) Override DF bit in IPv4 header of decapsulated
269  *                  output frame.
270  *
271  * If ODF = 1, DF is replaced with the value of DFV bit.
272  * Valid only from SEC Era 5 onwards.
273  */
274 #define PDBHMO_ESP_ODF		(0x08 << PDBHMO_ESP_DECAP_SHIFT)
275 
276 /**
277  * struct ipsec_encap_cbc - PDB part for IPsec CBC encapsulation
278  * @iv: 16-byte array initialization vector
279  */
280 struct ipsec_encap_cbc {
281 	uint8_t iv[16];
282 };
283 
284 
285 /**
286  * struct ipsec_encap_ctr - PDB part for IPsec CTR encapsulation
287  * @ctr_nonce: 4-byte nonce
288  * @ctr_initial: initial count constant
289  * @iv: initialization vector
290  */
291 struct ipsec_encap_ctr {
292 	uint32_t ctr_nonce;
293 	uint32_t ctr_initial;
294 	uint8_t iv[8];
295 };
296 
297 /**
298  * struct ipsec_encap_ccm - PDB part for IPsec CCM encapsulation
299  * @salt: 3-byte array salt (lower 24 bits)
300  * @ccm_opt: CCM algorithm options - MSB-LSB description:
301  *  b0_flags (8b) - CCM B0; use 0x5B for 8-byte ICV, 0x6B for 12-byte ICV,
302  *    0x7B for 16-byte ICV (cf. RFC4309, RFC3610)
303  *  ctr_flags (8b) - counter flags; constant equal to 0x3
304  *  ctr_initial (16b) - initial count constant
305  * @iv: initialization vector
306  */
307 struct ipsec_encap_ccm {
308 	uint8_t salt[4];
309 	uint32_t ccm_opt;
310 	uint64_t iv;
311 };
312 
313 /**
314  * struct ipsec_encap_gcm - PDB part for IPsec GCM encapsulation
315  * @salt: 3-byte array salt (lower 24 bits)
316  * @rsvd: reserved, do not use
317  * @iv: initialization vector
318  */
319 struct ipsec_encap_gcm {
320 	uint8_t salt[4];
321 	uint32_t rsvd;
322 	uint64_t iv;
323 };
324 
325 /**
326  * struct ipsec_encap_pdb - PDB for IPsec encapsulation
327  * @options: MSB-LSB description (both for legacy and new modes)
328  *  hmo (header manipulation options) - 4b
329  *  reserved - 4b
330  *  next header (legacy) / reserved (new) - 8b
331  *  next header offset (legacy) / AOIPHO (actual outer IP header offset) - 8b
332  *  option flags (depend on selected algorithm) - 8b
333  * @seq_num_ext_hi: (optional) IPsec Extended Sequence Number (ESN)
334  * @seq_num: IPsec sequence number
335  * @spi: IPsec SPI (Security Parameters Index)
336  * @ip_hdr_len: optional IP Header length (in bytes)
337  *  IP header must follow directly after ipsec_encap_pdb
338  */
339 struct ipsec_encap_pdb {
340 	uint32_t options;
341 	uint32_t seq_num_ext_hi;
342 	uint32_t seq_num;
343 	union {
344 		struct ipsec_encap_cbc cbc;
345 		struct ipsec_encap_ctr ctr;
346 		struct ipsec_encap_ccm ccm;
347 		struct ipsec_encap_gcm gcm;
348 	};
349 	uint32_t spi;
350 	uint32_t ip_hdr_len;
351 };
352 
353 static inline unsigned int
__rta_copy_ipsec_encap_pdb(struct program * program,struct ipsec_encap_pdb * pdb,uint32_t algtype)354 __rta_copy_ipsec_encap_pdb(struct program *program,
355 			   struct ipsec_encap_pdb *pdb,
356 			   uint32_t algtype)
357 {
358 	unsigned int start_pc = program->current_pc;
359 
360 	__rta_out32(program, pdb->options);
361 	__rta_out32(program, pdb->seq_num_ext_hi);
362 	__rta_out32(program, pdb->seq_num);
363 
364 	switch (algtype & OP_PCL_IPSEC_CIPHER_MASK) {
365 	case OP_PCL_IPSEC_DES_IV64:
366 	case OP_PCL_IPSEC_DES:
367 	case OP_PCL_IPSEC_3DES:
368 	case OP_PCL_IPSEC_AES_CBC:
369 	case OP_PCL_IPSEC_NULL:
370 		rta_copy_data(program, pdb->cbc.iv, sizeof(pdb->cbc.iv));
371 		break;
372 
373 	case OP_PCL_IPSEC_AES_CTR:
374 		rta_copy_data(program, (uint8_t *)&pdb->ctr.ctr_nonce, 4);
375 		__rta_out32(program, pdb->ctr.ctr_initial);
376 		rta_copy_data(program, pdb->ctr.iv, sizeof(pdb->ctr.iv));
377 		break;
378 
379 	case OP_PCL_IPSEC_AES_CCM8:
380 	case OP_PCL_IPSEC_AES_CCM12:
381 	case OP_PCL_IPSEC_AES_CCM16:
382 		rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
383 		__rta_out32(program, pdb->ccm.ccm_opt);
384 		__rta_out64(program, true, pdb->ccm.iv);
385 		break;
386 
387 	case OP_PCL_IPSEC_AES_GCM8:
388 	case OP_PCL_IPSEC_AES_GCM12:
389 	case OP_PCL_IPSEC_AES_GCM16:
390 	case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
391 		rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
392 		__rta_out32(program, pdb->gcm.rsvd);
393 		__rta_out64(program, true, pdb->gcm.iv);
394 		break;
395 	}
396 
397 	__rta_out32(program, pdb->spi);
398 	__rta_out32(program, pdb->ip_hdr_len);
399 
400 	return start_pc;
401 }
402 
403 /**
404  * struct ipsec_decap_cbc - PDB part for IPsec CBC decapsulation
405  * @rsvd: reserved, do not use
406  */
407 struct ipsec_decap_cbc {
408 	uint32_t rsvd[2];
409 };
410 
411 /**
412  * struct ipsec_decap_ctr - PDB part for IPsec CTR decapsulation
413  * @ctr_nonce: 4-byte nonce
414  * @ctr_initial: initial count constant
415  */
416 struct ipsec_decap_ctr {
417 	uint32_t ctr_nonce;
418 	uint32_t ctr_initial;
419 };
420 
421 /**
422  * struct ipsec_decap_ccm - PDB part for IPsec CCM decapsulation
423  * @salt: 3-byte salt (lower 24 bits)
424  * @ccm_opt: CCM algorithm options - MSB-LSB description:
425  *  b0_flags (8b) - CCM B0; use 0x5B for 8-byte ICV, 0x6B for 12-byte ICV,
426  *    0x7B for 16-byte ICV (cf. RFC4309, RFC3610)
427  *  ctr_flags (8b) - counter flags; constant equal to 0x3
428  *  ctr_initial (16b) - initial count constant
429  */
430 struct ipsec_decap_ccm {
431 	uint8_t salt[4];
432 	uint32_t ccm_opt;
433 };
434 
435 /**
436  * struct ipsec_decap_gcm - PDB part for IPsec GCN decapsulation
437  * @salt: 4-byte salt
438  * @rsvd: reserved, do not use
439  */
440 struct ipsec_decap_gcm {
441 	uint8_t salt[4];
442 	uint32_t rsvd;
443 };
444 
445 /**
446  * struct ipsec_decap_pdb - PDB for IPsec decapsulation
447  * @options: MSB-LSB description (both for legacy and new modes)
448  *  hmo (header manipulation options) - 4b
449  *  IP header length - 12b
450  *  next header offset (legacy) / AOIPHO (actual outer IP header offset) - 8b
451  *  option flags (depend on selected algorithm) - 8b
452  * @seq_num_ext_hi: (optional) IPsec Extended Sequence Number (ESN)
453  * @seq_num: IPsec sequence number
454  * @anti_replay: Anti-replay window; size depends on ARS (option flags);
455  *  format must be Big Endian, irrespective of platform
456  */
457 struct ipsec_decap_pdb {
458 	uint32_t options;
459 	union {
460 		struct ipsec_decap_cbc cbc;
461 		struct ipsec_decap_ctr ctr;
462 		struct ipsec_decap_ccm ccm;
463 		struct ipsec_decap_gcm gcm;
464 	};
465 	uint32_t seq_num_ext_hi;
466 	uint32_t seq_num;
467 	uint32_t anti_replay[32];
468 };
469 
470 static inline unsigned int
__rta_copy_ipsec_decap_pdb(struct program * program,struct ipsec_decap_pdb * pdb,uint32_t algtype)471 __rta_copy_ipsec_decap_pdb(struct program *program,
472 			   struct ipsec_decap_pdb *pdb,
473 			   uint32_t algtype)
474 {
475 	unsigned int start_pc = program->current_pc;
476 	unsigned int i, ars;
477 	uint8_t mask;
478 
479 	__rta_out32(program, pdb->options);
480 
481 	switch (algtype & OP_PCL_IPSEC_CIPHER_MASK) {
482 	case OP_PCL_IPSEC_DES_IV64:
483 	case OP_PCL_IPSEC_DES:
484 	case OP_PCL_IPSEC_3DES:
485 	case OP_PCL_IPSEC_AES_CBC:
486 	case OP_PCL_IPSEC_NULL:
487 		__rta_out32(program, pdb->cbc.rsvd[0]);
488 		__rta_out32(program, pdb->cbc.rsvd[1]);
489 		break;
490 
491 	case OP_PCL_IPSEC_AES_CTR:
492 		rta_copy_data(program, (uint8_t *)&pdb->ctr.ctr_nonce, 4);
493 		__rta_out32(program, pdb->ctr.ctr_initial);
494 		break;
495 
496 	case OP_PCL_IPSEC_AES_CCM8:
497 	case OP_PCL_IPSEC_AES_CCM12:
498 	case OP_PCL_IPSEC_AES_CCM16:
499 		rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
500 		__rta_out32(program, pdb->ccm.ccm_opt);
501 		break;
502 
503 	case OP_PCL_IPSEC_AES_GCM8:
504 	case OP_PCL_IPSEC_AES_GCM12:
505 	case OP_PCL_IPSEC_AES_GCM16:
506 	case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
507 		rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
508 		__rta_out32(program, pdb->gcm.rsvd);
509 		break;
510 	}
511 
512 	__rta_out32(program, pdb->seq_num_ext_hi);
513 	__rta_out32(program, pdb->seq_num);
514 
515 	if (rta_sec_era < RTA_SEC_ERA_10)
516 		mask = PDBOPTS_ESP_ARS_MASK;
517 	else
518 		mask = PDBOPTS_ESP_ARS_MASK_ERA10;
519 	switch (pdb->options & mask) {
520 	case PDBOPTS_ESP_ARS1024:
521 		ars = 32;
522 		break;
523 	case PDBOPTS_ESP_ARS512:
524 		ars = 16;
525 		break;
526 	case PDBOPTS_ESP_ARS256:
527 		ars = 8;
528 		break;
529 	case PDBOPTS_ESP_ARS128:
530 		ars = 4;
531 		break;
532 	case PDBOPTS_ESP_ARS64:
533 		ars = 2;
534 		break;
535 	case PDBOPTS_ESP_ARS32:
536 		ars = 1;
537 		break;
538 	case PDBOPTS_ESP_ARSNONE:
539 	default:
540 		ars = 0;
541 		break;
542 	}
543 
544 	for (i = 0; i < ars; i++)
545 		__rta_out_be32(program, pdb->anti_replay[i]);
546 
547 	return start_pc;
548 }
549 
550 /**
551  * enum ipsec_icv_size - Type selectors for icv size in IPsec protocol
552  * @IPSEC_ICV_MD5_SIZE: full-length MD5 ICV
553  * @IPSEC_ICV_MD5_TRUNC_SIZE: truncated MD5 ICV
554  */
555 enum ipsec_icv_size {
556 	IPSEC_ICV_MD5_SIZE = 16,
557 	IPSEC_ICV_MD5_TRUNC_SIZE = 12
558 };
559 
560 /*
561  * IPSec ESP Datapath Protocol Override Register (DPOVRD)
562  * IPSEC_N_* defines are for IPsec new mode.
563  */
564 
565 /**
566  * IPSEC_DPOVRD_USE - DPOVRD will override values specified in the PDB
567  */
568 #define IPSEC_DPOVRD_USE	BIT(31)
569 
570 /**
571  * IPSEC_DPOVRD_ECN_SHIFT - Explicit Congestion Notification
572  *
573  * If set, MSB of the 4 bits indicates that the 2 LSBs will replace the ECN bits
574  * in the IP header.
575  */
576 #define IPSEC_DPOVRD_ECN_SHIFT		24
577 
578 /**
579  * IPSEC_DPOVRD_ECN_MASK - See IPSEC_DPOVRD_ECN_SHIFT
580  */
581 #define IPSEC_DPOVRD_ECN_MASK		(0xf << IPSEC_ENCAP_DPOVRD_ECN_SHIFT)
582 
583 /**
584  * IPSEC_DPOVRD_IP_HDR_LEN_SHIFT - The length (in bytes) of the portion of the
585  *                                 IP header that is not encrypted
586  */
587 #define IPSEC_DPOVRD_IP_HDR_LEN_SHIFT	16
588 
589 /**
590  * IPSEC_DPOVRD_IP_HDR_LEN_MASK - See IPSEC_DPOVRD_IP_HDR_LEN_SHIFT
591  */
592 #define IPSEC_DPOVRD_IP_HDR_LEN_MASK	(0xff << IPSEC_DPOVRD_IP_HDR_LEN_SHIFT)
593 
594 /**
595  * IPSEC_DPOVRD_NH_OFFSET_SHIFT - The location of the next header field within
596  *                                the IP header of the transport mode packet
597  *
598  * Encap:
599  *	ESP_Trailer_NH <-- IP_Hdr[DPOVRD[NH_OFFSET]]
600  *	IP_Hdr[DPOVRD[NH_OFFSET]] <-- DPOVRD[NH]
601  *Decap:
602  *	IP_Hdr[DPOVRD[NH_OFFSET]] <-- ESP_Trailer_NH
603  */
604 #define IPSEC_DPOVRD_NH_OFFSET_SHIFT	8
605 
606 /**
607  * IPSEC_DPOVRD_NH_OFFSET_MASK - See IPSEC_DPOVRD_NH_OFFSET_SHIFT
608  */
609 #define IPSEC_DPOVRD_NH_OFFSET_MASK	(0xff << IPSEC_DPOVRD_NH_OFFSET_SHIFT)
610 
611 /**
612  * IPSEC_DPOVRD_NH_MASK - See IPSEC_DPOVRD_NH_OFFSET_SHIFT
613  *                        Valid only for encapsulation.
614  */
615 #define IPSEC_DPOVRD_NH_MASK		0xff
616 
617 /**
618  * IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT - Outer IP header Material length (encap)
619  *                                      Valid only if L2_COPY is not set.
620  */
621 #define IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT	16
622 
623 /**
624  * IPSEC_N_ENCAP_DPOVRD_OIM_LEN_MASK - See IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT
625  */
626 #define IPSEC_N_ENCAP_DPOVRD_OIM_LEN_MASK \
627 	(0xfff << IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT)
628 
629 /**
630  * IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT - L2 header length
631  *                                     Valid only if L2_COPY is set.
632  */
633 #define IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT	16
634 
635 /**
636  * IPSEC_N_ENCAP_DPOVRD_L2_LEN_MASK - See IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT
637  */
638 #define IPSEC_N_ENCAP_DPOVRD_L2_LEN_MASK \
639 	(0xff << IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT)
640 
641 /**
642  * IPSEC_N_ENCAP_DPOVRD_OIMIF -  Outer IP header Material in Input Frame
643  */
644 #define IPSEC_N_ENCAP_DPOVRD_OIMIF		BIT(15)
645 
646 /**
647  * IPSEC_N_ENCAP_DPOVRD_L2_COPY - L2 header present in input frame
648  *
649  * Note: For Era <= 8, this bit is reserved (not used) by HW.
650  */
651 #define IPSEC_N_ENCAP_DPOVRD_L2_COPY		BIT(14)
652 
653 /**
654  * IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT - Actual Outer IP Header Offset (encap)
655  */
656 #define IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT	8
657 
658 /**
659  * IPSEC_N_ENCAP_DPOVRD_AOIPHO_MASK - See IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT
660  */
661 #define IPSEC_N_ENCAP_DPOVRD_AOIPHO_MASK \
662 	(0x3c << IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT)
663 
664 /**
665  * IPSEC_N_ENCAP_DPOVRD_NH_MASK -  Next Header
666  *
667  * Used in the Next Header field of the encapsulated payload.
668  */
669 #define IPSEC_N_ENCAP_DPOVRD_NH_MASK		0xff
670 
671 /**
672  * IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT - Actual Outer IP Header Offset (decap)
673  */
674 #define IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT	12
675 
676 /**
677  * IPSEC_N_DECAP_DPOVRD_AOIPHO_MASK - See IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT
678  */
679 #define IPSEC_N_DECAP_DPOVRD_AOIPHO_MASK \
680 	(0xff << IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT)
681 
682 /**
683  * IPSEC_N_DECAP_DPOVRD_OIM_LEN_MASK - Outer IP header Material length (decap)
684  */
685 #define IPSEC_N_DECAP_DPOVRD_OIM_LEN_MASK	0xfff
686 
__gen_auth_key(struct program * program,struct alginfo * authdata)687 static inline void __gen_auth_key(struct program *program,
688 				  struct alginfo *authdata)
689 {
690 	uint32_t dkp_protid;
691 
692 	switch (authdata->algtype & OP_PCL_IPSEC_AUTH_MASK) {
693 	case OP_PCL_IPSEC_HMAC_MD5_96:
694 	case OP_PCL_IPSEC_HMAC_MD5_128:
695 		dkp_protid = OP_PCLID_DKP_MD5;
696 		break;
697 	case OP_PCL_IPSEC_HMAC_SHA1_96:
698 	case OP_PCL_IPSEC_HMAC_SHA1_160:
699 		dkp_protid = OP_PCLID_DKP_SHA1;
700 		break;
701 	case OP_PCL_IPSEC_HMAC_SHA2_256_128:
702 		dkp_protid = OP_PCLID_DKP_SHA256;
703 		break;
704 	case OP_PCL_IPSEC_HMAC_SHA2_384_192:
705 		dkp_protid = OP_PCLID_DKP_SHA384;
706 		break;
707 	case OP_PCL_IPSEC_HMAC_SHA2_512_256:
708 		dkp_protid = OP_PCLID_DKP_SHA512;
709 		break;
710 	case OP_PCL_IPSEC_HMAC_SHA2_224_96:
711 	case OP_PCL_IPSEC_HMAC_SHA2_224_112:
712 	case OP_PCL_IPSEC_HMAC_SHA2_224_224:
713 		dkp_protid = OP_PCLID_DKP_SHA224;
714 		break;
715 	default:
716 		KEY(program, KEY2, authdata->key_enc_flags, authdata->key,
717 		    authdata->keylen, INLINE_KEY(authdata));
718 		return;
719 	}
720 
721 	if (authdata->key_type == RTA_DATA_PTR)
722 		DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_PTR,
723 			     OP_PCL_DKP_DST_PTR, (uint16_t)authdata->keylen,
724 			     authdata->key, authdata->key_type);
725 	else
726 		DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_IMM,
727 			     OP_PCL_DKP_DST_IMM, (uint16_t)authdata->keylen,
728 			     authdata->key, authdata->key_type);
729 }
730 
731 /**
732  * rta_inline_ipsec_query() - Provide indications on which data items can be inlined
733  *                      and which shall be referenced in IPsec shared descriptor.
734  * @sd_base_len: Shared descriptor base length - bytes consumed by the commands,
735  *               excluding the data items to be inlined (or corresponding
736  *               pointer if an item is not inlined). Each cnstr_* function that
737  *               generates descriptors should have a define mentioning
738  *               corresponding length.
739  * @jd_len: Maximum length of the job descriptor(s) that will be used
740  *          together with the shared descriptor.
741  * @data_len: Array of lengths of the data items trying to be inlined
742  * @inl_mask: 32bit mask with bit x = 1 if data item x can be inlined, 0
743  *            otherwise.
744  * @count: Number of data items (size of @data_len array); must be <= 32
745  * @auth_algtype: Authentication algorithm type.
746  * @auth_index: Index value of data_len for authentication key length.
747  *		-1 if authentication key length is not present in data_len.
748  *
749  * Return: 0 if data can be inlined / referenced, negative value if not. If 0,
750  *         check @inl_mask for details.
751  */
752 static inline int
rta_inline_ipsec_query(unsigned int sd_base_len,unsigned int jd_len,unsigned int * data_len,uint32_t * inl_mask,unsigned int count,uint32_t auth_algtype,int32_t auth_index)753 rta_inline_ipsec_query(unsigned int sd_base_len,
754 		       unsigned int jd_len,
755 		       unsigned int *data_len,
756 		       uint32_t *inl_mask,
757 		       unsigned int count,
758 		       uint32_t auth_algtype,
759 		       int32_t auth_index)
760 {
761 	uint32_t dkp_protid;
762 
763 	switch (auth_algtype & OP_PCL_IPSEC_AUTH_MASK) {
764 	case OP_PCL_IPSEC_HMAC_MD5_96:
765 	case OP_PCL_IPSEC_HMAC_MD5_128:
766 		dkp_protid = OP_PCLID_DKP_MD5;
767 		break;
768 	case OP_PCL_IPSEC_HMAC_SHA1_96:
769 	case OP_PCL_IPSEC_HMAC_SHA1_160:
770 		dkp_protid = OP_PCLID_DKP_SHA1;
771 		break;
772 	case OP_PCL_IPSEC_HMAC_SHA2_256_128:
773 		dkp_protid = OP_PCLID_DKP_SHA256;
774 		break;
775 	case OP_PCL_IPSEC_HMAC_SHA2_384_192:
776 		dkp_protid = OP_PCLID_DKP_SHA384;
777 		break;
778 	case OP_PCL_IPSEC_HMAC_SHA2_512_256:
779 		dkp_protid = OP_PCLID_DKP_SHA512;
780 		break;
781 	case OP_PCL_IPSEC_HMAC_SHA2_224_96:
782 	case OP_PCL_IPSEC_HMAC_SHA2_224_112:
783 	case OP_PCL_IPSEC_HMAC_SHA2_224_224:
784 		dkp_protid = OP_PCLID_DKP_SHA224;
785 		break;
786 	default:
787 		return rta_inline_query(sd_base_len,
788 				       jd_len,
789 				       data_len,
790 				       inl_mask, count);
791 	}
792 
793 	/* Updating the maximum supported inline key length */
794 	if (auth_index != -1) {
795 		if (split_key_len(dkp_protid) > data_len[auth_index])
796 			data_len[auth_index] = split_key_len(dkp_protid);
797 	}
798 	return rta_inline_query(sd_base_len,
799 			       jd_len,
800 			       data_len,
801 			       inl_mask, count);
802 }
803 
804 /**
805  * cnstr_shdsc_ipsec_encap - IPSec ESP encapsulation protocol-level shared
806  *                           descriptor.
807  * @descbuf: pointer to buffer used for descriptor construction
808  * @ps: if 36/40bit addressing is desired, this parameter must be true
809  * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
810  * @share: sharing type of shared descriptor
811  * @pdb: pointer to the PDB to be used with this descriptor
812  *       This structure will be copied inline to the descriptor under
813  *       construction. No error checking will be made. Refer to the
814  *       block guide for a details of the encapsulation PDB.
815  * @cipherdata: pointer to block cipher transform definitions
816  *              Valid algorithm values - one of OP_PCL_IPSEC_*
817  * @authdata: pointer to authentication transform definitions
818  *            If an authentication key is required by the protocol:
819  *            -For SEC Eras 1-5, an MDHA split key must be provided;
820  *            Note that the size of the split key itself must be specified.
821  *            -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
822  *            Key Protocol) will be used to compute MDHA on the fly in HW.
823  *            Valid algorithm values - one of OP_PCL_IPSEC_*
824  *
825  * Return: size of descriptor written in words or negative number on error
826  */
827 static inline int
cnstr_shdsc_ipsec_encap(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct ipsec_encap_pdb * pdb,struct alginfo * cipherdata,struct alginfo * authdata)828 cnstr_shdsc_ipsec_encap(uint32_t *descbuf, bool ps, bool swap,
829 					  enum rta_share_type share,
830 			struct ipsec_encap_pdb *pdb,
831 			struct alginfo *cipherdata,
832 			struct alginfo *authdata)
833 {
834 	struct program prg;
835 	struct program *p = &prg;
836 
837 	LABEL(keyjmp);
838 	REFERENCE(pkeyjmp);
839 	LABEL(hdr);
840 	REFERENCE(phdr);
841 
842 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
843 	if (swap)
844 		PROGRAM_SET_BSWAP(p);
845 	if (ps)
846 		PROGRAM_SET_36BIT_ADDR(p);
847 	phdr = SHR_HDR(p, share, hdr, 0);
848 	__rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
849 
850 	/* IP header if any follows the encap_pdb */
851 	if (pdb->ip_hdr_len > 0) {
852 		void *ip_hdr = pdb + 1;
853 		COPY_DATA(p, ip_hdr, pdb->ip_hdr_len);
854 	}
855 	SET_LABEL(p, hdr);
856 	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
857 	if (authdata->keylen)
858 		__gen_auth_key(p, authdata);
859 
860 	if (cipherdata->keylen)
861 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
862 		    cipherdata->keylen, INLINE_KEY(cipherdata));
863 	SET_LABEL(p, keyjmp);
864 	PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
865 		 OP_PCLID_IPSEC,
866 		 (uint16_t)(cipherdata->algtype | authdata->algtype));
867 	PATCH_JUMP(p, pkeyjmp, keyjmp);
868 	PATCH_HDR(p, phdr, hdr);
869 	return PROGRAM_FINALIZE(p);
870 }
871 
872 /**
873  * cnstr_shdsc_ipsec_decap - IPSec ESP decapsulation protocol-level shared
874  *                           descriptor.
875  * @descbuf: pointer to buffer used for descriptor construction
876  * @ps: if 36/40bit addressing is desired, this parameter must be true
877  * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
878  * @share: sharing type of shared descriptor
879  * @pdb: pointer to the PDB to be used with this descriptor
880  *       This structure will be copied inline to the descriptor under
881  *       construction. No error checking will be made. Refer to the
882  *       block guide for details about the decapsulation PDB.
883  * @cipherdata: pointer to block cipher transform definitions.
884  *              Valid algorithm values - one of OP_PCL_IPSEC_*
885  * @authdata: pointer to authentication transform definitions
886  *            If an authentication key is required by the protocol:
887  *            -For SEC Eras 1-5, an MDHA split key must be provided;
888  *            Note that the size of the split key itself must be specified.
889  *            -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
890  *            Key Protocol) will be used to compute MDHA on the fly in HW.
891  *            Valid algorithm values - one of OP_PCL_IPSEC_*
892  *
893  * Return: size of descriptor written in words or negative number on error
894  */
895 static inline int
cnstr_shdsc_ipsec_decap(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct ipsec_decap_pdb * pdb,struct alginfo * cipherdata,struct alginfo * authdata)896 cnstr_shdsc_ipsec_decap(uint32_t *descbuf, bool ps, bool swap,
897 			enum rta_share_type share,
898 			struct ipsec_decap_pdb *pdb,
899 			struct alginfo *cipherdata,
900 			struct alginfo *authdata)
901 {
902 	struct program prg;
903 	struct program *p = &prg;
904 
905 	LABEL(keyjmp);
906 	REFERENCE(pkeyjmp);
907 	LABEL(hdr);
908 	REFERENCE(phdr);
909 
910 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
911 	if (swap)
912 		PROGRAM_SET_BSWAP(p);
913 	if (ps)
914 		PROGRAM_SET_36BIT_ADDR(p);
915 	phdr = SHR_HDR(p, share, hdr, 0);
916 	__rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
917 	SET_LABEL(p, hdr);
918 	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
919 	if (authdata->keylen)
920 		__gen_auth_key(p, authdata);
921 
922 	if (cipherdata->keylen)
923 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
924 		    cipherdata->keylen, INLINE_KEY(cipherdata));
925 	SET_LABEL(p, keyjmp);
926 	PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
927 		 OP_PCLID_IPSEC,
928 		 (uint16_t)(cipherdata->algtype | authdata->algtype));
929 	PATCH_JUMP(p, pkeyjmp, keyjmp);
930 	PATCH_HDR(p, phdr, hdr);
931 	return PROGRAM_FINALIZE(p);
932 }
933 
934 /**
935  * cnstr_shdsc_ipsec_encap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
936  *     AES-XCBC-MAC-96 ESP encapsulation shared descriptor.
937  * @descbuf: pointer to buffer used for descriptor construction
938  * @share: sharing type of shared descriptor
939  * @pdb: pointer to the PDB to be used with this descriptor
940  *       This structure will be copied inline to the descriptor under
941  *       construction. No error checking will be made. Refer to the
942  *       block guide for a details of the encapsulation PDB.
943  * @cipherdata: pointer to block cipher transform definitions
944  *              Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
945  * @authdata: pointer to authentication transform definitions
946  *            Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
947  *
948  * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
949  * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
950  * Outer/Transport IP Header is present in the encapsulation output packet.
951  * The descriptor performs DES-CBC/3DES-CBC & HMAC-MD5-96 and then rereads
952  * the input packet to do the AES-XCBC-MAC-96 calculation and to overwrite
953  * the MD5 ICV.
954  * The descriptor uses all the benefits of the built-in protocol by computing
955  * the IPsec ESP with a hardware supported algorithms combination
956  * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
957  * was chosen in order to speed up the computational time for this intermediate
958  * step.
959  * Warning: The user must allocate at least 32 bytes for the authentication key
960  * (in order to use it also with HMAC-MD5-96),even when using a shorter key
961  * for the AES-XCBC-MAC-96.
962  *
963  * Return: size of descriptor written in words or negative number on error
964  */
965 static inline int
cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t * descbuf,enum rta_share_type share,struct ipsec_encap_pdb * pdb,struct alginfo * cipherdata,struct alginfo * authdata)966 cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
967 				     enum rta_share_type share,
968 				     struct ipsec_encap_pdb *pdb,
969 				     struct alginfo *cipherdata,
970 				     struct alginfo *authdata)
971 {
972 	struct program prg;
973 	struct program *p = &prg;
974 
975 	LABEL(hdr);
976 	LABEL(shd_ptr);
977 	LABEL(keyjump);
978 	LABEL(outptr);
979 	LABEL(swapped_seqin_fields);
980 	LABEL(swapped_seqin_ptr);
981 	REFERENCE(phdr);
982 	REFERENCE(pkeyjump);
983 	REFERENCE(move_outlen);
984 	REFERENCE(move_seqout_ptr);
985 	REFERENCE(swapped_seqin_ptr_jump);
986 	REFERENCE(write_swapped_seqin_ptr);
987 
988 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
989 	phdr = SHR_HDR(p, share, hdr, 0);
990 	__rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
991 
992 	/* IP header if any follows the encap_pdb */
993 	if (pdb->ip_hdr_len > 0) {
994 		void *ip_hdr = pdb + 1;
995 		COPY_DATA(p, ip_hdr, pdb->ip_hdr_len);
996 	}
997 
998 	SET_LABEL(p, hdr);
999 	pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
1000 	/*
1001 	 * Hard-coded KEY arguments. The descriptor uses all the benefits of
1002 	 * the built-in protocol by computing the IPsec ESP with a hardware
1003 	 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
1004 	 * The HMAC-MD5 authentication algorithm was chosen with
1005 	 * the keys options from below in order to speed up the computational
1006 	 * time for this intermediate step.
1007 	 * Warning: The user must allocate at least 32 bytes for
1008 	 * the authentication key (in order to use it also with HMAC-MD5-96),
1009 	 * even when using a shorter key for the AES-XCBC-MAC-96.
1010 	 */
1011 	KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
1012 	SET_LABEL(p, keyjump);
1013 	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
1014 	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
1015 	     IMMED);
1016 	KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1017 	    cipherdata->keylen, INLINE_KEY(cipherdata));
1018 	PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL, OP_PCLID_IPSEC,
1019 		 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
1020 	/* Swap SEQINPTR to SEQOUTPTR. */
1021 	move_seqout_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
1022 	MATHB(p, MATH1, AND, ~(CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR), MATH1,
1023 	      8, IFB | IMMED2);
1024 /*
1025  * TODO: RTA currently doesn't support creating a LOAD command
1026  * with another command as IMM.
1027  * To be changed when proper support is added in RTA.
1028  */
1029 	LOAD(p, 0xa00000e5, MATH3, 4, 4, IMMED);
1030 	MATHB(p, MATH3, SHLD, MATH3, MATH3,  8, 0);
1031 	write_swapped_seqin_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
1032 				       IMMED);
1033 	swapped_seqin_ptr_jump = JUMP(p, swapped_seqin_ptr, LOCAL_JUMP,
1034 				      ALL_TRUE, 0);
1035 	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
1036 	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
1037 	     0);
1038 	SEQOUTPTR(p, 0, 65535, RTO);
1039 	move_outlen = MOVE(p, DESCBUF, 0, MATH0, 4, 8, WAITCOMP | IMMED);
1040 	MATHB(p, MATH0, SUB,
1041 	      (uint64_t)(pdb->ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE),
1042 	      VSEQINSZ, 4, IMMED2);
1043 	MATHB(p, MATH0, SUB, IPSEC_ICV_MD5_TRUNC_SIZE, VSEQOUTSZ, 4, IMMED2);
1044 	KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
1045 	    0);
1046 	ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
1047 		      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
1048 	SEQFIFOLOAD(p, SKIP, pdb->ip_hdr_len, 0);
1049 	SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1 | LAST1);
1050 	SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
1051 	SEQSTORE(p, CONTEXT1, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
1052 /*
1053  * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
1054  * To be changed when proper support is added in RTA.
1055  */
1056 	/* Label the Shared Descriptor Pointer */
1057 	SET_LABEL(p, shd_ptr);
1058 	shd_ptr += 1;
1059 	/* Label the Output Pointer */
1060 	SET_LABEL(p, outptr);
1061 	outptr += 3;
1062 	/* Label the first word after JD */
1063 	SET_LABEL(p, swapped_seqin_fields);
1064 	swapped_seqin_fields += 8;
1065 	/* Label the second word after JD */
1066 	SET_LABEL(p, swapped_seqin_ptr);
1067 	swapped_seqin_ptr += 9;
1068 
1069 	PATCH_HDR(p, phdr, hdr);
1070 	PATCH_JUMP(p, pkeyjump, keyjump);
1071 	PATCH_JUMP(p, swapped_seqin_ptr_jump, swapped_seqin_ptr);
1072 	PATCH_MOVE(p, move_outlen, outptr);
1073 	PATCH_MOVE(p, move_seqout_ptr, shd_ptr);
1074 	PATCH_MOVE(p, write_swapped_seqin_ptr, swapped_seqin_fields);
1075 	return PROGRAM_FINALIZE(p);
1076 }
1077 
1078 /**
1079  * cnstr_shdsc_ipsec_decap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
1080  *     AES-XCBC-MAC-96 ESP decapsulation shared descriptor.
1081  * @descbuf: pointer to buffer used for descriptor construction
1082  * @share: sharing type of shared descriptor
1083  * @pdb: pointer to the PDB to be used with this descriptor
1084  *       This structure will be copied inline to the descriptor under
1085  *       construction. No error checking will be made. Refer to the
1086  *       block guide for a details of the encapsulation PDB.
1087  * @cipherdata: pointer to block cipher transform definitions
1088  *              Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
1089  * @authdata: pointer to authentication transform definitions
1090  *            Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
1091  *
1092  * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
1093  * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
1094  * Outer/Transport IP Header is present in the decapsulation input packet.
1095  * The descriptor computes the AES-XCBC-MAC-96 to check if the received ICV
1096  * is correct, rereads the input packet to compute the MD5 ICV, overwrites
1097  * the XCBC ICV, and then sends the modified input packet to the
1098  * DES-CBC/3DES-CBC & HMAC-MD5-96 IPsec.
1099  * The descriptor uses all the benefits of the built-in protocol by computing
1100  * the IPsec ESP with a hardware supported algorithms combination
1101  * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
1102  * was chosen in order to speed up the computational time for this intermediate
1103  * step.
1104  * Warning: The user must allocate at least 32 bytes for the authentication key
1105  * (in order to use it also with HMAC-MD5-96),even when using a shorter key
1106  * for the AES-XCBC-MAC-96.
1107  *
1108  * Return: size of descriptor written in words or negative number on error
1109  */
1110 static inline int
cnstr_shdsc_ipsec_decap_des_aes_xcbc(uint32_t * descbuf,enum rta_share_type share,struct ipsec_decap_pdb * pdb,struct alginfo * cipherdata,struct alginfo * authdata)1111 cnstr_shdsc_ipsec_decap_des_aes_xcbc(uint32_t *descbuf,
1112 				     enum rta_share_type share,
1113 				     struct ipsec_decap_pdb *pdb,
1114 				     struct alginfo *cipherdata,
1115 				     struct alginfo *authdata)
1116 {
1117 	struct program prg;
1118 	struct program *p = &prg;
1119 	uint32_t ip_hdr_len = (pdb->options & PDBHDRLEN_MASK) >>
1120 				PDBHDRLEN_ESP_DECAP_SHIFT;
1121 
1122 	LABEL(hdr);
1123 	LABEL(jump_cmd);
1124 	LABEL(keyjump);
1125 	LABEL(outlen);
1126 	LABEL(seqin_ptr);
1127 	LABEL(seqout_ptr);
1128 	LABEL(swapped_seqout_fields);
1129 	LABEL(swapped_seqout_ptr);
1130 	REFERENCE(seqout_ptr_jump);
1131 	REFERENCE(phdr);
1132 	REFERENCE(pkeyjump);
1133 	REFERENCE(move_jump);
1134 	REFERENCE(move_jump_back);
1135 	REFERENCE(move_seqin_ptr);
1136 	REFERENCE(swapped_seqout_ptr_jump);
1137 	REFERENCE(write_swapped_seqout_ptr);
1138 
1139 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
1140 	phdr = SHR_HDR(p, share, hdr, 0);
1141 	__rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
1142 	SET_LABEL(p, hdr);
1143 	pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
1144 	/*
1145 	 * Hard-coded KEY arguments. The descriptor uses all the benefits of
1146 	 * the built-in protocol by computing the IPsec ESP with a hardware
1147 	 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
1148 	 * The HMAC-MD5 authentication algorithm was chosen with
1149 	 * the keys options from bellow in order to speed up the computational
1150 	 * time for this intermediate step.
1151 	 * Warning: The user must allocate at least 32 bytes for
1152 	 * the authentication key (in order to use it also with HMAC-MD5-96),
1153 	 * even when using a shorter key for the AES-XCBC-MAC-96.
1154 	 */
1155 	KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
1156 	SET_LABEL(p, keyjump);
1157 	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
1158 	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
1159 	     0);
1160 	KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
1161 	    INLINE_KEY(authdata));
1162 	MATHB(p, SEQINSZ, SUB,
1163 	      (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), MATH0, 4,
1164 	      IMMED2);
1165 	MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
1166 	ALG_OPERATION(p, OP_ALG_ALGSEL_MD5, OP_ALG_AAI_HMAC_PRECOMP,
1167 		      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
1168 	ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
1169 		      OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
1170 	SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
1171 	SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1);
1172 	SEQFIFOLOAD(p, ICV1, IPSEC_ICV_MD5_TRUNC_SIZE, FLUSH1 | LAST1);
1173 	/* Swap SEQOUTPTR to SEQINPTR. */
1174 	move_seqin_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
1175 	MATHB(p, MATH1, OR, CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR, MATH1, 8,
1176 	      IFB | IMMED2);
1177 /*
1178  * TODO: RTA currently doesn't support creating a LOAD command
1179  * with another command as IMM.
1180  * To be changed when proper support is added in RTA.
1181  */
1182 	LOAD(p, 0xA00000e1, MATH3, 4, 4, IMMED);
1183 	MATHB(p, MATH3, SHLD, MATH3, MATH3,  8, 0);
1184 	write_swapped_seqout_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
1185 					IMMED);
1186 	swapped_seqout_ptr_jump = JUMP(p, swapped_seqout_ptr, LOCAL_JUMP,
1187 				       ALL_TRUE, 0);
1188 /*
1189  * TODO: To be changed when proper support is added in RTA (can't load
1190  * a command that is also written by RTA).
1191  * Change when proper RTA support is added.
1192  */
1193 	SET_LABEL(p, jump_cmd);
1194 	WORD(p, 0xA00000f3);
1195 	SEQINPTR(p, 0, 65535, RTO);
1196 	MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
1197 	MATHB(p, MATH0, ADD, ip_hdr_len, VSEQOUTSZ, 4, IMMED2);
1198 	move_jump = MOVE(p, DESCBUF, 0, OFIFO, 0, 8, WAITCOMP | IMMED);
1199 	move_jump_back = MOVE(p, OFIFO, 0, DESCBUF, 0, 8, IMMED);
1200 	SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
1201 	SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
1202 	SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
1203 	SEQSTORE(p, CONTEXT2, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
1204 	seqout_ptr_jump = JUMP(p, seqout_ptr, LOCAL_JUMP, ALL_TRUE, CALM);
1205 
1206 	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
1207 	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_CLR_C2MODE |
1208 	     CLRW_CLR_C2DATAS | CLRW_CLR_C2CTX | CLRW_RESET_CLS1_CHA, CLRW, 0,
1209 	     4, 0);
1210 	SEQINPTR(p, 0, 65535, RTO);
1211 	MATHB(p, MATH0, ADD,
1212 	      (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), SEQINSZ, 4,
1213 	      IMMED2);
1214 	KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1215 	    cipherdata->keylen, INLINE_KEY(cipherdata));
1216 	PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL, OP_PCLID_IPSEC,
1217 		 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
1218 /*
1219  * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
1220  * To be changed when proper support is added in RTA.
1221  */
1222 	/* Label the SEQ OUT PTR */
1223 	SET_LABEL(p, seqout_ptr);
1224 	seqout_ptr += 2;
1225 	/* Label the Output Length */
1226 	SET_LABEL(p, outlen);
1227 	outlen += 4;
1228 	/* Label the SEQ IN PTR */
1229 	SET_LABEL(p, seqin_ptr);
1230 	seqin_ptr += 5;
1231 	/* Label the first word after JD */
1232 	SET_LABEL(p, swapped_seqout_fields);
1233 	swapped_seqout_fields += 8;
1234 	/* Label the second word after JD */
1235 	SET_LABEL(p, swapped_seqout_ptr);
1236 	swapped_seqout_ptr += 9;
1237 
1238 	PATCH_HDR(p, phdr, hdr);
1239 	PATCH_JUMP(p, pkeyjump, keyjump);
1240 	PATCH_JUMP(p, seqout_ptr_jump, seqout_ptr);
1241 	PATCH_JUMP(p, swapped_seqout_ptr_jump, swapped_seqout_ptr);
1242 	PATCH_MOVE(p, move_jump, jump_cmd);
1243 	PATCH_MOVE(p, move_jump_back, seqin_ptr);
1244 	PATCH_MOVE(p, move_seqin_ptr, outlen);
1245 	PATCH_MOVE(p, write_swapped_seqout_ptr, swapped_seqout_fields);
1246 	return PROGRAM_FINALIZE(p);
1247 }
1248 
1249 /**
1250  * IPSEC_NEW_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor length
1251  *
1252  * Accounts only for the "base" commands and is intended to be used by upper
1253  * layers to determine whether Outer IP Header and/or keys can be inlined or
1254  * not. To be used as first parameter of rta_inline_query().
1255  */
1256 #define IPSEC_NEW_ENC_BASE_DESC_LEN	(12 * CAAM_CMD_SZ + \
1257 					 sizeof(struct ipsec_encap_pdb))
1258 
1259 /**
1260  * IPSEC_NEW_NULL_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor
1261  *                                    length for the case of
1262  *                                    NULL encryption / authentication
1263  *
1264  * Accounts only for the "base" commands and is intended to be used by upper
1265  * layers to determine whether Outer IP Header and/or key can be inlined or
1266  * not. To be used as first parameter of rta_inline_query().
1267  */
1268 #define IPSEC_NEW_NULL_ENC_BASE_DESC_LEN	(11 * CAAM_CMD_SZ + \
1269 						 sizeof(struct ipsec_encap_pdb))
1270 
1271 /**
1272  * cnstr_shdsc_ipsec_new_encap -  IPSec new mode ESP encapsulation
1273  *     protocol-level shared descriptor.
1274  * @descbuf: pointer to buffer used for descriptor construction
1275  * @ps: if 36/40bit addressing is desired, this parameter must be true
1276  * @swap: must be true when core endianness doesn't match SEC endianness
1277  * @share: sharing type of shared descriptor
1278  * @pdb: pointer to the PDB to be used with this descriptor
1279  *       This structure will be copied inline to the descriptor under
1280  *       construction. No error checking will be made. Refer to the
1281  *       block guide for details about the encapsulation PDB.
1282  * @opt_ip_hdr:  pointer to Optional IP Header
1283  *     -if OIHI = PDBOPTS_ESP_OIHI_PDB_INL, opt_ip_hdr points to the buffer to
1284  *     be inlined in the PDB. Number of bytes (buffer size) copied is provided
1285  *     in pdb->ip_hdr_len.
1286  *     -if OIHI = PDBOPTS_ESP_OIHI_PDB_REF, opt_ip_hdr points to the address of
1287  *     the Optional IP Header. The address will be inlined in the PDB verbatim.
1288  *     -for other values of OIHI options field, opt_ip_hdr is not used.
1289  * @cipherdata: pointer to block cipher transform definitions
1290  *              Valid algorithm values - one of OP_PCL_IPSEC_*
1291  * @authdata: pointer to authentication transform definitions.
1292  *            If an authentication key is required by the protocol, a "normal"
1293  *            key must be provided; DKP (Derived Key Protocol) will be used to
1294  *            compute MDHA on the fly in HW.
1295  *            Valid algorithm values - one of OP_PCL_IPSEC_*
1296  *
1297  * Note: L2 header copy functionality is implemented assuming that bits 14
1298  * (currently reserved) and 16-23 (part of Outer IP Header Material Length)
1299  * in DPOVRD register are not used (which is usually the case when L3 header
1300  * is provided in PDB).
1301  * When DPOVRD[14] is set, frame starts with an L2 header; in this case, the
1302  * L2 header length is found at DPOVRD[23:16]. SEC uses this length to copy
1303  * the header and then it deletes DPOVRD[23:16] (so there is no side effect
1304  * when later running IPsec protocol).
1305  *
1306  * Return: size of descriptor written in words or negative number on error
1307  */
1308 static inline int
cnstr_shdsc_ipsec_new_encap(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct ipsec_encap_pdb * pdb,uint8_t * opt_ip_hdr,struct alginfo * cipherdata,struct alginfo * authdata)1309 cnstr_shdsc_ipsec_new_encap(uint32_t *descbuf, bool ps,
1310 			    bool swap,
1311 			    enum rta_share_type share,
1312 			    struct ipsec_encap_pdb *pdb,
1313 			    uint8_t *opt_ip_hdr,
1314 			    struct alginfo *cipherdata,
1315 			    struct alginfo *authdata)
1316 {
1317 	struct program prg;
1318 	struct program *p = &prg;
1319 
1320 	LABEL(keyjmp);
1321 	REFERENCE(pkeyjmp);
1322 	LABEL(hdr);
1323 	REFERENCE(phdr);
1324 	LABEL(l2copy);
1325 	REFERENCE(pl2copy);
1326 
1327 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
1328 	if (swap)
1329 		PROGRAM_SET_BSWAP(p);
1330 	if (ps)
1331 		PROGRAM_SET_36BIT_ADDR(p);
1332 	phdr = SHR_HDR(p, share, hdr, 0);
1333 
1334 	__rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
1335 
1336 	switch (pdb->options & PDBOPTS_ESP_OIHI_MASK) {
1337 	case PDBOPTS_ESP_OIHI_PDB_INL:
1338 		COPY_DATA(p, opt_ip_hdr, pdb->ip_hdr_len);
1339 		break;
1340 	case PDBOPTS_ESP_OIHI_PDB_REF:
1341 		if (ps)
1342 			COPY_DATA(p, opt_ip_hdr, 8);
1343 		else
1344 			COPY_DATA(p, opt_ip_hdr, 4);
1345 		break;
1346 	default:
1347 		break;
1348 	}
1349 	SET_LABEL(p, hdr);
1350 
1351 	MATHB(p, DPOVRD, AND, IPSEC_N_ENCAP_DPOVRD_L2_COPY, NONE, 4, IMMED2);
1352 	pl2copy = JUMP(p, l2copy, LOCAL_JUMP, ALL_TRUE, MATH_Z);
1353 	MATHI(p, DPOVRD, RSHIFT, IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT, VSEQOUTSZ,
1354 	      1, 0);
1355 	MATHB(p, DPOVRD, AND, ~IPSEC_N_ENCAP_DPOVRD_L2_LEN_MASK, DPOVRD, 4,
1356 	      IMMED2);
1357 	/* TODO: CLASS2 corresponds to AUX=2'b10; add more intuitive defines */
1358 	SEQFIFOSTORE(p, METADATA, 0, 0, CLASS2 | VLF);
1359 	SET_LABEL(p, l2copy);
1360 
1361 	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1362 	if (authdata->keylen)
1363 		__gen_auth_key(p, authdata);
1364 	if (cipherdata->keylen)
1365 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1366 		    cipherdata->keylen, INLINE_KEY(cipherdata));
1367 	SET_LABEL(p, keyjmp);
1368 	PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
1369 		 OP_PCLID_IPSEC_NEW,
1370 		 (uint16_t)(cipherdata->algtype | authdata->algtype));
1371 	PATCH_JUMP(p, pl2copy, l2copy);
1372 	PATCH_JUMP(p, pkeyjmp, keyjmp);
1373 	PATCH_HDR(p, phdr, hdr);
1374 	return PROGRAM_FINALIZE(p);
1375 }
1376 
1377 /**
1378  * IPSEC_NEW_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor length
1379  *
1380  * Accounts only for the "base" commands and is intended to be used by upper
1381  * layers to determine whether keys can be inlined or not. To be used as first
1382  * parameter of rta_inline_query().
1383  */
1384 #define IPSEC_NEW_DEC_BASE_DESC_LEN	(5 * CAAM_CMD_SZ + \
1385 					 sizeof(struct ipsec_decap_pdb))
1386 
1387 /**
1388  * IPSEC_NEW_NULL_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor
1389  *                                    length for the case of
1390  *                                    NULL decryption / authentication
1391  *
1392  * Accounts only for the "base" commands and is intended to be used by upper
1393  * layers to determine whether key can be inlined or not. To be used as first
1394  * parameter of rta_inline_query().
1395  */
1396 #define IPSEC_NEW_NULL_DEC_BASE_DESC_LEN	(4 * CAAM_CMD_SZ + \
1397 						 sizeof(struct ipsec_decap_pdb))
1398 
1399 /**
1400  * cnstr_shdsc_ipsec_new_decap - IPSec new mode ESP decapsulation protocol-level
1401  *     shared descriptor.
1402  * @descbuf: pointer to buffer used for descriptor construction
1403  * @ps: if 36/40bit addressing is desired, this parameter must be true
1404  * @swap: must be true when core endianness doesn't match SEC endianness
1405  * @share: sharing type of shared descriptor
1406  * @pdb: pointer to the PDB to be used with this descriptor
1407  *       This structure will be copied inline to the descriptor under
1408  *       construction. No error checking will be made. Refer to the
1409  *       block guide for details about the decapsulation PDB.
1410  * @cipherdata: pointer to block cipher transform definitions
1411  *              Valid algorithm values 0 one of OP_PCL_IPSEC_*
1412  * @authdata: pointer to authentication transform definitions.
1413  *            If an authentication key is required by the protocol, a "normal"
1414  *            key must be provided; DKP (Derived Key Protocol) will be used to
1415  *            compute MDHA on the fly in HW.
1416  *            Valid algorithm values - one of OP_PCL_IPSEC_*
1417  *
1418  * Return: size of descriptor written in words or negative number on error
1419  */
1420 static inline int
cnstr_shdsc_ipsec_new_decap(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct ipsec_decap_pdb * pdb,struct alginfo * cipherdata,struct alginfo * authdata)1421 cnstr_shdsc_ipsec_new_decap(uint32_t *descbuf, bool ps,
1422 			    bool swap,
1423 			    enum rta_share_type share,
1424 			    struct ipsec_decap_pdb *pdb,
1425 			    struct alginfo *cipherdata,
1426 			    struct alginfo *authdata)
1427 {
1428 	struct program prg;
1429 	struct program *p = &prg;
1430 
1431 	LABEL(keyjmp);
1432 	REFERENCE(pkeyjmp);
1433 	LABEL(hdr);
1434 	REFERENCE(phdr);
1435 
1436 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
1437 	if (swap)
1438 		PROGRAM_SET_BSWAP(p);
1439 	if (ps)
1440 		PROGRAM_SET_36BIT_ADDR(p);
1441 	phdr = SHR_HDR(p, share, hdr, 0);
1442 	__rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
1443 	SET_LABEL(p, hdr);
1444 	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1445 	if (authdata->keylen)
1446 		__gen_auth_key(p, authdata);
1447 	if (cipherdata->keylen)
1448 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1449 		    cipherdata->keylen, INLINE_KEY(cipherdata));
1450 	SET_LABEL(p, keyjmp);
1451 	PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
1452 		 OP_PCLID_IPSEC_NEW,
1453 		 (uint16_t)(cipherdata->algtype | authdata->algtype));
1454 	PATCH_JUMP(p, pkeyjmp, keyjmp);
1455 	PATCH_HDR(p, phdr, hdr);
1456 	return PROGRAM_FINALIZE(p);
1457 }
1458 
1459 /**
1460  * IPSEC_AUTH_VAR_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1461  *				for the case of variable-length authentication
1462  *				only data.
1463  *				Note: Only for SoCs with SEC_ERA >= 3.
1464  *
1465  * Accounts only for the "base" commands and is intended to be used by upper
1466  * layers to determine whether keys can be inlined or not. To be used as first
1467  * parameter of rta_inline_query().
1468  */
1469 #define IPSEC_AUTH_VAR_BASE_DESC_LEN	(31 * CAAM_CMD_SZ)
1470 
1471 /**
1472  * IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor
1473  *                              length for variable-length authentication only
1474  *                              data.
1475  *                              Note: Only for SoCs with SEC_ERA >= 3.
1476  *
1477  * Accounts only for the "base" commands and is intended to be used by upper
1478  * layers to determine whether key can be inlined or not. To be used as first
1479  * parameter of rta_inline_query().
1480  */
1481 #define IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN	\
1482 				(IPSEC_AUTH_VAR_BASE_DESC_LEN + CAAM_CMD_SZ)
1483 
1484 /**
1485  * IPSEC_AUTH_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1486  *
1487  * Accounts only for the "base" commands and is intended to be used by upper
1488  * layers to determine whether key can be inlined or not. To be used as first
1489  * parameter of rta_inline_query().
1490  */
1491 #define IPSEC_AUTH_BASE_DESC_LEN	(19 * CAAM_CMD_SZ)
1492 
1493 /**
1494  * IPSEC_AUTH_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor length
1495  *
1496  * Accounts only for the "base" commands and is intended to be used by upper
1497  * layers to determine whether key can be inlined or not. To be used as first
1498  * parameter of rta_inline_query().
1499  */
1500 #define IPSEC_AUTH_AES_DEC_BASE_DESC_LEN	(IPSEC_AUTH_BASE_DESC_LEN + \
1501 						CAAM_CMD_SZ)
1502 
1503 /**
1504  * cnstr_shdsc_authenc - authenc-like descriptor
1505  * @descbuf: pointer to buffer used for descriptor construction
1506  * @ps: if 36/40bit addressing is desired, this parameter must be true
1507  * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
1508  * @share: sharing type of shared descriptor
1509  * @cipherdata: pointer to block cipher transform definitions.
1510  *              Valid algorithm values one of OP_ALG_ALGSEL_* {DES, 3DES, AES}
1511  *              Valid modes for:
1512  *                  AES: OP_ALG_AAI_* {CBC, CTR}
1513  *                  DES, 3DES: OP_ALG_AAI_CBC
1514  * @authdata: pointer to authentication transform definitions.
1515  *            Valid algorithm values - one of OP_ALG_ALGSEL_* {MD5, SHA1,
1516  *            SHA224, SHA256, SHA384, SHA512}
1517  * Note: The key for authentication is supposed to be given as plain text.
1518  * Note: There's no support for keys longer than the block size of the
1519  *       underlying hash function, according to the selected algorithm.
1520  *
1521  * @ivlen: length of the IV to be read from the input frame, before any data
1522  *         to be processed
1523  *
1524  * @trunc_len: the length of the ICV to be written to the output frame. If 0,
1525  *             then the corresponding length of the digest, according to the
1526  *             selected algorithm shall be used.
1527  * @dir: Protocol direction, encapsulation or decapsulation (DIR_ENC/DIR_DEC)
1528  *
1529  * Note: Here's how the input frame needs to be formatted so that the processing
1530  *       will be done correctly:
1531  * For encapsulation:
1532  *     Input:
1533  * +----+----------------+-----------------------------------------------+
1534  * | IV | Auth-only head | Padded data to be auth & Enc | Auth-only tail |
1535  * +----+----------------+-----------------------------------------------+
1536  *     Output:
1537  * +--------------------------------------+
1538  * | Authenticated & Encrypted data | ICV |
1539  * +--------------------------------+-----+
1540  *
1541  * For decapsulation:
1542  *     Input:
1543  * +----+----------------+-----------------+----------------------+
1544  * | IV | Auth-only head | Auth & Enc data | Auth-only tail | ICV |
1545  * +----+----------------+-----------------+----------------------+
1546  *     Output:
1547  * +----+---------------------------+
1548  * | Decrypted & authenticated data |
1549  * +----+---------------------------+
1550  *
1551  * Note: This descriptor can use per-packet commands, encoded as below in the
1552  *       DPOVRD register:
1553  * 32    28               16	         1
1554  * +------+------------------------------+
1555  * | 0x8  | auth_tail_len | auth_hdr_len |
1556  * +------+------------------------------+
1557  *
1558  * This mechanism is available only for SoCs having SEC ERA >= 3. In other
1559  * words, this will not work for P4080TO2
1560  *
1561  * Note: The descriptor does not add any kind of padding to the input data,
1562  *       so the upper layer needs to ensure that the data is padded properly,
1563  *       according to the selected cipher. Failure to do so will result in
1564  *       the descriptor failing with a data-size error.
1565  *
1566  * Return: size of descriptor written in words or negative number on error
1567  */
1568 static inline int
cnstr_shdsc_authenc(uint32_t * descbuf,bool ps,bool swap,enum rta_share_type share,struct alginfo * cipherdata,struct alginfo * authdata,uint16_t ivlen,uint8_t trunc_len,uint8_t dir)1569 cnstr_shdsc_authenc(uint32_t *descbuf, bool ps, bool swap,
1570 		    enum rta_share_type share,
1571 		    struct alginfo *cipherdata,
1572 		    struct alginfo *authdata,
1573 		    uint16_t ivlen,
1574 		    uint8_t trunc_len, uint8_t dir)
1575 {
1576 	struct program prg;
1577 	struct program *p = &prg;
1578 	const bool need_dk = (dir == DIR_DEC) &&
1579 			     (cipherdata->algtype == OP_ALG_ALGSEL_AES) &&
1580 			     (cipherdata->algmode == OP_ALG_AAI_CBC);
1581 	int data_type;
1582 
1583 	LABEL(keyjmp);
1584 	LABEL(skipkeys);
1585 	LABEL(proc_icv);
1586 	LABEL(no_auth_tail);
1587 	REFERENCE(pkeyjmp);
1588 	REFERENCE(pskipkeys);
1589 	REFERENCE(p_proc_icv);
1590 	REFERENCE(p_no_auth_tail);
1591 
1592 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
1593 
1594 	if (swap)
1595 		PROGRAM_SET_BSWAP(p);
1596 	if (ps)
1597 		PROGRAM_SET_36BIT_ADDR(p);
1598 
1599 	/*
1600 	 * Since we currently assume that key length is equal to hash digest
1601 	 * size, it's ok to truncate keylen value.
1602 	 */
1603 	trunc_len = trunc_len && (trunc_len < authdata->keylen) ?
1604 			trunc_len : (uint8_t)authdata->keylen;
1605 
1606 	SHR_HDR(p, share, 1, SC);
1607 
1608 	/* Collect the (auth_tail || auth_hdr) len from DPOVRD */
1609 	MATHB(p, DPOVRD, ADD, 0x80000000, MATH2, 4, IMMED2);
1610 
1611 	/* Get auth_hdr len in MATH0 */
1612 	MATHB(p, MATH2, AND, 0xFFFF, MATH0, 4, IMMED2);
1613 
1614 	/* Get auth_tail len in MATH2 */
1615 	MATHB(p, MATH2, AND, 0xFFF0000, MATH2, 4, IMMED2);
1616 	MATHI(p, MATH2, RSHIFT, 16, MATH2, 4, IMMED2);
1617 
1618 	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1619 
1620 	KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1621 	    INLINE_KEY(authdata));
1622 
1623 	/* Insert Key */
1624 	KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1625 	    cipherdata->keylen, INLINE_KEY(cipherdata));
1626 
1627 	/* Do operation */
1628 	ALG_OPERATION(p, authdata->algtype, authdata->algmode,
1629 		      OP_ALG_AS_INITFINAL,
1630 		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1631 		      dir);
1632 
1633 	if (need_dk)
1634 		ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode,
1635 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1636 	pskipkeys = JUMP(p, skipkeys, LOCAL_JUMP, ALL_TRUE, 0);
1637 
1638 	SET_LABEL(p, keyjmp);
1639 
1640 	if (authdata->algmode == OP_ALG_AAI_HMAC)
1641 		ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
1642 		      OP_ALG_AS_INITFINAL,
1643 		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1644 		      dir);
1645 	else
1646 		ALG_OPERATION(p, authdata->algtype, authdata->algmode,
1647 		      OP_ALG_AS_INITFINAL,
1648 		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1649 		      dir);
1650 
1651 	if (need_dk) {
1652 		ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode |
1653 			      OP_ALG_AAI_DK, OP_ALG_AS_INITFINAL,
1654 			      ICV_CHECK_DISABLE, dir);
1655 		SET_LABEL(p, skipkeys);
1656 	} else {
1657 		SET_LABEL(p, skipkeys);
1658 		ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
1659 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1660 	}
1661 
1662 	/* Read IV */
1663 	if (cipherdata->algmode == OP_ALG_AAI_CTR)
1664 		SEQLOAD(p, CONTEXT1, 16, ivlen, 0);
1665 	else
1666 		SEQLOAD(p, CONTEXT1, 0, ivlen, 0);
1667 
1668 	/*
1669 	 * authenticate auth_hdr data
1670 	 */
1671 	MATHB(p, MATH0, ADD, ZERO, VSEQINSZ, 4, 0);
1672 	SEQFIFOLOAD(p, MSG2, 0, VLF);
1673 
1674 	/*
1675 	 * Prepare the length of the data to be both encrypted/decrypted
1676 	 * and authenticated/checked
1677 	 */
1678 	MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
1679 	if (dir == DIR_DEC) {
1680 		MATHB(p, VSEQINSZ, SUB, trunc_len, VSEQINSZ, 4, IMMED2);
1681 		data_type = MSGINSNOOP;
1682 	} else {
1683 		data_type = MSGOUTSNOOP;
1684 	}
1685 
1686 	MATHB(p, VSEQINSZ, ADD, ZERO, VSEQOUTSZ, 4, 0);
1687 
1688 	/* Prepare for writing the output frame */
1689 	SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1690 
1691 
1692 	/* Check if there is no auth-tail */
1693 	MATHB(p, MATH2, ADD, ZERO, MATH2, 4, 0);
1694 	p_no_auth_tail = JUMP(p, no_auth_tail, LOCAL_JUMP, ALL_TRUE, MATH_Z);
1695 
1696 	/*
1697 	 * Read input plain/cipher text, encrypt/decrypt & auth & write
1698 	 * to output
1699 	 */
1700 	SEQFIFOLOAD(p, data_type, 0, VLF | LAST1 | FLUSH1);
1701 
1702 	/* Authenticate auth tail */
1703 	MATHB(p, MATH2, ADD, ZERO, VSEQINSZ, 4, 0);
1704 	SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
1705 
1706 	/* Jump to process icv */
1707 	p_proc_icv = JUMP(p, proc_icv, LOCAL_JUMP, ALL_FALSE, MATH_Z);
1708 
1709 	SET_LABEL(p, no_auth_tail);
1710 
1711 	SEQFIFOLOAD(p, data_type, 0, VLF | LAST1 | LAST2 | FLUSH1);
1712 
1713 	SET_LABEL(p, proc_icv);
1714 
1715 	if (dir == DIR_ENC)
1716 		/* Finally, write the ICV */
1717 		SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
1718 	else
1719 		/* Read the ICV to check */
1720 		SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
1721 
1722 	PATCH_JUMP(p, pkeyjmp, keyjmp);
1723 	PATCH_JUMP(p, pskipkeys, skipkeys);
1724 	PATCH_JUMP(p, p_no_auth_tail, no_auth_tail);
1725 	PATCH_JUMP(p, p_proc_icv, proc_icv);
1726 	return PROGRAM_FINALIZE(p);
1727 }
1728 
1729 #endif /* __DESC_IPSEC_H__ */
1730