xref: /dpdk/drivers/common/dpaax/caamflib/desc/ipsec.h (revision 882f2538)
1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2008-2016 Freescale Semiconductor Inc.
4  * Copyright 2016,2019-2020 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  *  reserved - 16b
338  *  Opt. IP Hdr Len - 16b
339  * @ip_hdr: optional IP Header content (only for IPsec legacy mode)
340  */
341 struct ipsec_encap_pdb {
342 	uint32_t options;
343 	uint32_t seq_num_ext_hi;
344 	uint32_t seq_num;
345 	union {
346 		struct ipsec_encap_cbc cbc;
347 		struct ipsec_encap_ctr ctr;
348 		struct ipsec_encap_ccm ccm;
349 		struct ipsec_encap_gcm gcm;
350 	};
351 	uint32_t spi;
352 	uint32_t ip_hdr_len;
353 	uint8_t ip_hdr[0];
354 };
355 
356 static inline unsigned int
__rta_copy_ipsec_encap_pdb(struct program * program,struct ipsec_encap_pdb * pdb,uint32_t algtype)357 __rta_copy_ipsec_encap_pdb(struct program *program,
358 			   struct ipsec_encap_pdb *pdb,
359 			   uint32_t algtype)
360 {
361 	unsigned int start_pc = program->current_pc;
362 
363 	__rta_out32(program, pdb->options);
364 	__rta_out32(program, pdb->seq_num_ext_hi);
365 	__rta_out32(program, pdb->seq_num);
366 
367 	switch (algtype & OP_PCL_IPSEC_CIPHER_MASK) {
368 	case OP_PCL_IPSEC_DES_IV64:
369 	case OP_PCL_IPSEC_DES:
370 	case OP_PCL_IPSEC_3DES:
371 	case OP_PCL_IPSEC_AES_CBC:
372 	case OP_PCL_IPSEC_NULL:
373 		rta_copy_data(program, pdb->cbc.iv, sizeof(pdb->cbc.iv));
374 		break;
375 
376 	case OP_PCL_IPSEC_AES_CTR:
377 		rta_copy_data(program, (uint8_t *)&pdb->ctr.ctr_nonce, 4);
378 		__rta_out32(program, pdb->ctr.ctr_initial);
379 		rta_copy_data(program, pdb->ctr.iv, sizeof(pdb->ctr.iv));
380 		break;
381 
382 	case OP_PCL_IPSEC_AES_CCM8:
383 	case OP_PCL_IPSEC_AES_CCM12:
384 	case OP_PCL_IPSEC_AES_CCM16:
385 		rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
386 		__rta_out32(program, pdb->ccm.ccm_opt);
387 		__rta_out64(program, true, pdb->ccm.iv);
388 		break;
389 
390 	case OP_PCL_IPSEC_AES_GCM8:
391 	case OP_PCL_IPSEC_AES_GCM12:
392 	case OP_PCL_IPSEC_AES_GCM16:
393 	case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
394 		rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
395 		__rta_out32(program, pdb->gcm.rsvd);
396 		__rta_out64(program, true, pdb->gcm.iv);
397 		break;
398 	}
399 
400 	__rta_out32(program, pdb->spi);
401 	__rta_out32(program, pdb->ip_hdr_len);
402 
403 	return start_pc;
404 }
405 
406 /**
407  * struct ipsec_decap_cbc - PDB part for IPsec CBC decapsulation
408  * @rsvd: reserved, do not use
409  */
410 struct ipsec_decap_cbc {
411 	uint32_t rsvd[2];
412 };
413 
414 /**
415  * struct ipsec_decap_ctr - PDB part for IPsec CTR decapsulation
416  * @ctr_nonce: 4-byte nonce
417  * @ctr_initial: initial count constant
418  */
419 struct ipsec_decap_ctr {
420 	uint32_t ctr_nonce;
421 	uint32_t ctr_initial;
422 };
423 
424 /**
425  * struct ipsec_decap_ccm - PDB part for IPsec CCM decapsulation
426  * @salt: 3-byte salt (lower 24 bits)
427  * @ccm_opt: CCM algorithm options - MSB-LSB description:
428  *  b0_flags (8b) - CCM B0; use 0x5B for 8-byte ICV, 0x6B for 12-byte ICV,
429  *    0x7B for 16-byte ICV (cf. RFC4309, RFC3610)
430  *  ctr_flags (8b) - counter flags; constant equal to 0x3
431  *  ctr_initial (16b) - initial count constant
432  */
433 struct ipsec_decap_ccm {
434 	uint8_t salt[4];
435 	uint32_t ccm_opt;
436 };
437 
438 /**
439  * struct ipsec_decap_gcm - PDB part for IPsec GCN decapsulation
440  * @salt: 4-byte salt
441  * @rsvd: reserved, do not use
442  */
443 struct ipsec_decap_gcm {
444 	uint8_t salt[4];
445 	uint32_t rsvd;
446 };
447 
448 /**
449  * struct ipsec_decap_pdb - PDB for IPsec decapsulation
450  * @options: MSB-LSB description (both for legacy and new modes)
451  *  hmo (header manipulation options) - 4b
452  *  IP header length - 12b
453  *  next header offset (legacy) / AOIPHO (actual outer IP header offset) - 8b
454  *  option flags (depend on selected algorithm) - 8b
455  * @seq_num_ext_hi: (optional) IPsec Extended Sequence Number (ESN)
456  * @seq_num: IPsec sequence number
457  * @anti_replay: Anti-replay window; size depends on ARS (option flags);
458  *  format must be Big Endian, irrespective of platform
459  */
460 struct ipsec_decap_pdb {
461 	uint32_t options;
462 	union {
463 		struct ipsec_decap_cbc cbc;
464 		struct ipsec_decap_ctr ctr;
465 		struct ipsec_decap_ccm ccm;
466 		struct ipsec_decap_gcm gcm;
467 	};
468 	uint32_t seq_num_ext_hi;
469 	uint32_t seq_num;
470 	uint32_t anti_replay[32];
471 };
472 
473 static inline unsigned int
__rta_copy_ipsec_decap_pdb(struct program * program,struct ipsec_decap_pdb * pdb,uint32_t algtype)474 __rta_copy_ipsec_decap_pdb(struct program *program,
475 			   struct ipsec_decap_pdb *pdb,
476 			   uint32_t algtype)
477 {
478 	unsigned int start_pc = program->current_pc;
479 	unsigned int i, ars;
480 	uint8_t mask;
481 
482 	__rta_out32(program, pdb->options);
483 
484 	switch (algtype & OP_PCL_IPSEC_CIPHER_MASK) {
485 	case OP_PCL_IPSEC_DES_IV64:
486 	case OP_PCL_IPSEC_DES:
487 	case OP_PCL_IPSEC_3DES:
488 	case OP_PCL_IPSEC_AES_CBC:
489 	case OP_PCL_IPSEC_NULL:
490 		__rta_out32(program, pdb->cbc.rsvd[0]);
491 		__rta_out32(program, pdb->cbc.rsvd[1]);
492 		break;
493 
494 	case OP_PCL_IPSEC_AES_CTR:
495 		rta_copy_data(program, (uint8_t *)&pdb->ctr.ctr_nonce, 4);
496 		__rta_out32(program, pdb->ctr.ctr_initial);
497 		break;
498 
499 	case OP_PCL_IPSEC_AES_CCM8:
500 	case OP_PCL_IPSEC_AES_CCM12:
501 	case OP_PCL_IPSEC_AES_CCM16:
502 		rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
503 		__rta_out32(program, pdb->ccm.ccm_opt);
504 		break;
505 
506 	case OP_PCL_IPSEC_AES_GCM8:
507 	case OP_PCL_IPSEC_AES_GCM12:
508 	case OP_PCL_IPSEC_AES_GCM16:
509 	case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
510 		rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
511 		__rta_out32(program, pdb->gcm.rsvd);
512 		break;
513 	}
514 
515 	__rta_out32(program, pdb->seq_num_ext_hi);
516 	__rta_out32(program, pdb->seq_num);
517 
518 	if (rta_sec_era < RTA_SEC_ERA_10)
519 		mask = PDBOPTS_ESP_ARS_MASK;
520 	else
521 		mask = PDBOPTS_ESP_ARS_MASK_ERA10;
522 	switch (pdb->options & mask) {
523 	case PDBOPTS_ESP_ARS1024:
524 		ars = 32;
525 		break;
526 	case PDBOPTS_ESP_ARS512:
527 		ars = 16;
528 		break;
529 	case PDBOPTS_ESP_ARS256:
530 		ars = 8;
531 		break;
532 	case PDBOPTS_ESP_ARS128:
533 		ars = 4;
534 		break;
535 	case PDBOPTS_ESP_ARS64:
536 		ars = 2;
537 		break;
538 	case PDBOPTS_ESP_ARS32:
539 		ars = 1;
540 		break;
541 	case PDBOPTS_ESP_ARSNONE:
542 	default:
543 		ars = 0;
544 		break;
545 	}
546 
547 	for (i = 0; i < ars; i++)
548 		__rta_out_be32(program, pdb->anti_replay[i]);
549 
550 	return start_pc;
551 }
552 
553 /**
554  * enum ipsec_icv_size - Type selectors for icv size in IPsec protocol
555  * @IPSEC_ICV_MD5_SIZE: full-length MD5 ICV
556  * @IPSEC_ICV_MD5_TRUNC_SIZE: truncated MD5 ICV
557  */
558 enum ipsec_icv_size {
559 	IPSEC_ICV_MD5_SIZE = 16,
560 	IPSEC_ICV_MD5_TRUNC_SIZE = 12
561 };
562 
563 /*
564  * IPSec ESP Datapath Protocol Override Register (DPOVRD)
565  * IPSEC_N_* defines are for IPsec new mode.
566  */
567 
568 /**
569  * IPSEC_DPOVRD_USE - DPOVRD will override values specified in the PDB
570  */
571 #define IPSEC_DPOVRD_USE	BIT(31)
572 
573 /**
574  * IPSEC_DPOVRD_ECN_SHIFT - Explicit Congestion Notification
575  *
576  * If set, MSB of the 4 bits indicates that the 2 LSBs will replace the ECN bits
577  * in the IP header.
578  */
579 #define IPSEC_DPOVRD_ECN_SHIFT		24
580 
581 /**
582  * IPSEC_DPOVRD_ECN_MASK - See IPSEC_DPOVRD_ECN_SHIFT
583  */
584 #define IPSEC_DPOVRD_ECN_MASK		(0xf << IPSEC_ENCAP_DPOVRD_ECN_SHIFT)
585 
586 /**
587  * IPSEC_DPOVRD_IP_HDR_LEN_SHIFT - The length (in bytes) of the portion of the
588  *                                 IP header that is not encrypted
589  */
590 #define IPSEC_DPOVRD_IP_HDR_LEN_SHIFT	16
591 
592 /**
593  * IPSEC_DPOVRD_IP_HDR_LEN_MASK - See IPSEC_DPOVRD_IP_HDR_LEN_SHIFT
594  */
595 #define IPSEC_DPOVRD_IP_HDR_LEN_MASK	(0xff << IPSEC_DPOVRD_IP_HDR_LEN_SHIFT)
596 
597 /**
598  * IPSEC_DPOVRD_NH_OFFSET_SHIFT - The location of the next header field within
599  *                                the IP header of the transport mode packet
600  *
601  * Encap:
602  *	ESP_Trailer_NH <-- IP_Hdr[DPOVRD[NH_OFFSET]]
603  *	IP_Hdr[DPOVRD[NH_OFFSET]] <-- DPOVRD[NH]
604  *Decap:
605  *	IP_Hdr[DPOVRD[NH_OFFSET]] <-- ESP_Trailer_NH
606  */
607 #define IPSEC_DPOVRD_NH_OFFSET_SHIFT	8
608 
609 /**
610  * IPSEC_DPOVRD_NH_OFFSET_MASK - See IPSEC_DPOVRD_NH_OFFSET_SHIFT
611  */
612 #define IPSEC_DPOVRD_NH_OFFSET_MASK	(0xff << IPSEC_DPOVRD_NH_OFFSET_SHIFT)
613 
614 /**
615  * IPSEC_DPOVRD_NH_MASK - See IPSEC_DPOVRD_NH_OFFSET_SHIFT
616  *                        Valid only for encapsulation.
617  */
618 #define IPSEC_DPOVRD_NH_MASK		0xff
619 
620 /**
621  * IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT - Outer IP header Material length (encap)
622  *                                      Valid only if L2_COPY is not set.
623  */
624 #define IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT	16
625 
626 /**
627  * IPSEC_N_ENCAP_DPOVRD_OIM_LEN_MASK - See IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT
628  */
629 #define IPSEC_N_ENCAP_DPOVRD_OIM_LEN_MASK \
630 	(0xfff << IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT)
631 
632 /**
633  * IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT - L2 header length
634  *                                     Valid only if L2_COPY is set.
635  */
636 #define IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT	16
637 
638 /**
639  * IPSEC_N_ENCAP_DPOVRD_L2_LEN_MASK - See IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT
640  */
641 #define IPSEC_N_ENCAP_DPOVRD_L2_LEN_MASK \
642 	(0xff << IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT)
643 
644 /**
645  * IPSEC_N_ENCAP_DPOVRD_OIMIF -  Outer IP header Material in Input Frame
646  */
647 #define IPSEC_N_ENCAP_DPOVRD_OIMIF		BIT(15)
648 
649 /**
650  * IPSEC_N_ENCAP_DPOVRD_L2_COPY - L2 header present in input frame
651  *
652  * Note: For Era <= 8, this bit is reserved (not used) by HW.
653  */
654 #define IPSEC_N_ENCAP_DPOVRD_L2_COPY		BIT(14)
655 
656 /**
657  * IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT - Actual Outer IP Header Offset (encap)
658  */
659 #define IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT	8
660 
661 /**
662  * IPSEC_N_ENCAP_DPOVRD_AOIPHO_MASK - See IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT
663  */
664 #define IPSEC_N_ENCAP_DPOVRD_AOIPHO_MASK \
665 	(0x3c << IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT)
666 
667 /**
668  * IPSEC_N_ENCAP_DPOVRD_NH_MASK -  Next Header
669  *
670  * Used in the Next Header field of the encapsulated payload.
671  */
672 #define IPSEC_N_ENCAP_DPOVRD_NH_MASK		0xff
673 
674 /**
675  * IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT - Actual Outer IP Header Offset (decap)
676  */
677 #define IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT	12
678 
679 /**
680  * IPSEC_N_DECAP_DPOVRD_AOIPHO_MASK - See IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT
681  */
682 #define IPSEC_N_DECAP_DPOVRD_AOIPHO_MASK \
683 	(0xff << IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT)
684 
685 /**
686  * IPSEC_N_DECAP_DPOVRD_OIM_LEN_MASK - Outer IP header Material length (decap)
687  */
688 #define IPSEC_N_DECAP_DPOVRD_OIM_LEN_MASK	0xfff
689 
__gen_auth_key(struct program * program,struct alginfo * authdata)690 static inline void __gen_auth_key(struct program *program,
691 				  struct alginfo *authdata)
692 {
693 	uint32_t dkp_protid;
694 
695 	switch (authdata->algtype & OP_PCL_IPSEC_AUTH_MASK) {
696 	case OP_PCL_IPSEC_HMAC_MD5_96:
697 	case OP_PCL_IPSEC_HMAC_MD5_128:
698 		dkp_protid = OP_PCLID_DKP_MD5;
699 		break;
700 	case OP_PCL_IPSEC_HMAC_SHA1_96:
701 	case OP_PCL_IPSEC_HMAC_SHA1_160:
702 		dkp_protid = OP_PCLID_DKP_SHA1;
703 		break;
704 	case OP_PCL_IPSEC_HMAC_SHA2_256_128:
705 		dkp_protid = OP_PCLID_DKP_SHA256;
706 		break;
707 	case OP_PCL_IPSEC_HMAC_SHA2_384_192:
708 		dkp_protid = OP_PCLID_DKP_SHA384;
709 		break;
710 	case OP_PCL_IPSEC_HMAC_SHA2_512_256:
711 		dkp_protid = OP_PCLID_DKP_SHA512;
712 		break;
713 	default:
714 		KEY(program, KEY2, authdata->key_enc_flags, authdata->key,
715 		    authdata->keylen, INLINE_KEY(authdata));
716 		return;
717 	}
718 
719 	if (authdata->key_type == RTA_DATA_PTR)
720 		DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_PTR,
721 			     OP_PCL_DKP_DST_PTR, (uint16_t)authdata->keylen,
722 			     authdata->key, authdata->key_type);
723 	else
724 		DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_IMM,
725 			     OP_PCL_DKP_DST_IMM, (uint16_t)authdata->keylen,
726 			     authdata->key, authdata->key_type);
727 }
728 
729 /**
730  * cnstr_shdsc_ipsec_encap - IPSec ESP encapsulation protocol-level shared
731  *                           descriptor.
732  * @descbuf: pointer to buffer used for descriptor construction
733  * @ps: if 36/40bit addressing is desired, this parameter must be true
734  * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
735  * @share: sharing type of shared descriptor
736  * @pdb: pointer to the PDB to be used with this descriptor
737  *       This structure will be copied inline to the descriptor under
738  *       construction. No error checking will be made. Refer to the
739  *       block guide for a details of the encapsulation PDB.
740  * @cipherdata: pointer to block cipher transform definitions
741  *              Valid algorithm values - one of OP_PCL_IPSEC_*
742  * @authdata: pointer to authentication transform definitions
743  *            If an authentication key is required by the protocol:
744  *            -For SEC Eras 1-5, an MDHA split key must be provided;
745  *            Note that the size of the split key itself must be specified.
746  *            -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
747  *            Key Protocol) will be used to compute MDHA on the fly in HW.
748  *            Valid algorithm values - one of OP_PCL_IPSEC_*
749  *
750  * Return: size of descriptor written in words or negative number on error
751  */
752 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)753 cnstr_shdsc_ipsec_encap(uint32_t *descbuf, bool ps, bool swap,
754 					  enum rta_share_type share,
755 			struct ipsec_encap_pdb *pdb,
756 			struct alginfo *cipherdata,
757 			struct alginfo *authdata)
758 {
759 	struct program prg;
760 	struct program *p = &prg;
761 
762 	LABEL(keyjmp);
763 	REFERENCE(pkeyjmp);
764 	LABEL(hdr);
765 	REFERENCE(phdr);
766 
767 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
768 	if (swap)
769 		PROGRAM_SET_BSWAP(p);
770 	if (ps)
771 		PROGRAM_SET_36BIT_ADDR(p);
772 	phdr = SHR_HDR(p, share, hdr, 0);
773 	__rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
774 	COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
775 	SET_LABEL(p, hdr);
776 	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
777 	if (authdata->keylen)
778 		__gen_auth_key(p, authdata);
779 
780 	if (cipherdata->keylen)
781 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
782 		    cipherdata->keylen, INLINE_KEY(cipherdata));
783 	SET_LABEL(p, keyjmp);
784 	PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
785 		 OP_PCLID_IPSEC,
786 		 (uint16_t)(cipherdata->algtype | authdata->algtype));
787 	PATCH_JUMP(p, pkeyjmp, keyjmp);
788 	PATCH_HDR(p, phdr, hdr);
789 	return PROGRAM_FINALIZE(p);
790 }
791 
792 /**
793  * cnstr_shdsc_ipsec_decap - IPSec ESP decapsulation protocol-level shared
794  *                           descriptor.
795  * @descbuf: pointer to buffer used for descriptor construction
796  * @ps: if 36/40bit addressing is desired, this parameter must be true
797  * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
798  * @share: sharing type of shared descriptor
799  * @pdb: pointer to the PDB to be used with this descriptor
800  *       This structure will be copied inline to the descriptor under
801  *       construction. No error checking will be made. Refer to the
802  *       block guide for details about the decapsulation PDB.
803  * @cipherdata: pointer to block cipher transform definitions.
804  *              Valid algorithm values - one of OP_PCL_IPSEC_*
805  * @authdata: pointer to authentication transform definitions
806  *            If an authentication key is required by the protocol:
807  *            -For SEC Eras 1-5, an MDHA split key must be provided;
808  *            Note that the size of the split key itself must be specified.
809  *            -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
810  *            Key Protocol) will be used to compute MDHA on the fly in HW.
811  *            Valid algorithm values - one of OP_PCL_IPSEC_*
812  *
813  * Return: size of descriptor written in words or negative number on error
814  */
815 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)816 cnstr_shdsc_ipsec_decap(uint32_t *descbuf, bool ps, bool swap,
817 			enum rta_share_type share,
818 			struct ipsec_decap_pdb *pdb,
819 			struct alginfo *cipherdata,
820 			struct alginfo *authdata)
821 {
822 	struct program prg;
823 	struct program *p = &prg;
824 
825 	LABEL(keyjmp);
826 	REFERENCE(pkeyjmp);
827 	LABEL(hdr);
828 	REFERENCE(phdr);
829 
830 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
831 	if (swap)
832 		PROGRAM_SET_BSWAP(p);
833 	if (ps)
834 		PROGRAM_SET_36BIT_ADDR(p);
835 	phdr = SHR_HDR(p, share, hdr, 0);
836 	__rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
837 	SET_LABEL(p, hdr);
838 	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
839 	if (authdata->keylen)
840 		__gen_auth_key(p, authdata);
841 
842 	if (cipherdata->keylen)
843 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
844 		    cipherdata->keylen, INLINE_KEY(cipherdata));
845 	SET_LABEL(p, keyjmp);
846 	PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
847 		 OP_PCLID_IPSEC,
848 		 (uint16_t)(cipherdata->algtype | authdata->algtype));
849 	PATCH_JUMP(p, pkeyjmp, keyjmp);
850 	PATCH_HDR(p, phdr, hdr);
851 	return PROGRAM_FINALIZE(p);
852 }
853 
854 /**
855  * cnstr_shdsc_ipsec_encap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
856  *     AES-XCBC-MAC-96 ESP encapsulation shared descriptor.
857  * @descbuf: pointer to buffer used for descriptor construction
858  * @share: sharing type of shared descriptor
859  * @pdb: pointer to the PDB to be used with this descriptor
860  *       This structure will be copied inline to the descriptor under
861  *       construction. No error checking will be made. Refer to the
862  *       block guide for a details of the encapsulation PDB.
863  * @cipherdata: pointer to block cipher transform definitions
864  *              Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
865  * @authdata: pointer to authentication transform definitions
866  *            Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
867  *
868  * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
869  * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
870  * Outer/Transport IP Header is present in the encapsulation output packet.
871  * The descriptor performs DES-CBC/3DES-CBC & HMAC-MD5-96 and then rereads
872  * the input packet to do the AES-XCBC-MAC-96 calculation and to overwrite
873  * the MD5 ICV.
874  * The descriptor uses all the benefits of the built-in protocol by computing
875  * the IPsec ESP with a hardware supported algorithms combination
876  * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
877  * was chosen in order to speed up the computational time for this intermediate
878  * step.
879  * Warning: The user must allocate at least 32 bytes for the authentication key
880  * (in order to use it also with HMAC-MD5-96),even when using a shorter key
881  * for the AES-XCBC-MAC-96.
882  *
883  * Return: size of descriptor written in words or negative number on error
884  */
885 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)886 cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
887 				     enum rta_share_type share,
888 				     struct ipsec_encap_pdb *pdb,
889 				     struct alginfo *cipherdata,
890 				     struct alginfo *authdata)
891 {
892 	struct program prg;
893 	struct program *p = &prg;
894 
895 	LABEL(hdr);
896 	LABEL(shd_ptr);
897 	LABEL(keyjump);
898 	LABEL(outptr);
899 	LABEL(swapped_seqin_fields);
900 	LABEL(swapped_seqin_ptr);
901 	REFERENCE(phdr);
902 	REFERENCE(pkeyjump);
903 	REFERENCE(move_outlen);
904 	REFERENCE(move_seqout_ptr);
905 	REFERENCE(swapped_seqin_ptr_jump);
906 	REFERENCE(write_swapped_seqin_ptr);
907 
908 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
909 	phdr = SHR_HDR(p, share, hdr, 0);
910 	__rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
911 	COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
912 	SET_LABEL(p, hdr);
913 	pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
914 	/*
915 	 * Hard-coded KEY arguments. The descriptor uses all the benefits of
916 	 * the built-in protocol by computing the IPsec ESP with a hardware
917 	 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
918 	 * The HMAC-MD5 authentication algorithm was chosen with
919 	 * the keys options from below in order to speed up the computational
920 	 * time for this intermediate step.
921 	 * Warning: The user must allocate at least 32 bytes for
922 	 * the authentication key (in order to use it also with HMAC-MD5-96),
923 	 * even when using a shorter key for the AES-XCBC-MAC-96.
924 	 */
925 	KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
926 	SET_LABEL(p, keyjump);
927 	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
928 	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
929 	     IMMED);
930 	KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
931 	    cipherdata->keylen, INLINE_KEY(cipherdata));
932 	PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL, OP_PCLID_IPSEC,
933 		 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
934 	/* Swap SEQINPTR to SEQOUTPTR. */
935 	move_seqout_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
936 	MATHB(p, MATH1, AND, ~(CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR), MATH1,
937 	      8, IFB | IMMED2);
938 /*
939  * TODO: RTA currently doesn't support creating a LOAD command
940  * with another command as IMM.
941  * To be changed when proper support is added in RTA.
942  */
943 	LOAD(p, 0xa00000e5, MATH3, 4, 4, IMMED);
944 	MATHB(p, MATH3, SHLD, MATH3, MATH3,  8, 0);
945 	write_swapped_seqin_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
946 				       IMMED);
947 	swapped_seqin_ptr_jump = JUMP(p, swapped_seqin_ptr, LOCAL_JUMP,
948 				      ALL_TRUE, 0);
949 	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
950 	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
951 	     0);
952 	SEQOUTPTR(p, 0, 65535, RTO);
953 	move_outlen = MOVE(p, DESCBUF, 0, MATH0, 4, 8, WAITCOMP | IMMED);
954 	MATHB(p, MATH0, SUB,
955 	      (uint64_t)(pdb->ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE),
956 	      VSEQINSZ, 4, IMMED2);
957 	MATHB(p, MATH0, SUB, IPSEC_ICV_MD5_TRUNC_SIZE, VSEQOUTSZ, 4, IMMED2);
958 	KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
959 	    0);
960 	ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
961 		      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
962 	SEQFIFOLOAD(p, SKIP, pdb->ip_hdr_len, 0);
963 	SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1 | LAST1);
964 	SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
965 	SEQSTORE(p, CONTEXT1, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
966 /*
967  * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
968  * To be changed when proper support is added in RTA.
969  */
970 	/* Label the Shared Descriptor Pointer */
971 	SET_LABEL(p, shd_ptr);
972 	shd_ptr += 1;
973 	/* Label the Output Pointer */
974 	SET_LABEL(p, outptr);
975 	outptr += 3;
976 	/* Label the first word after JD */
977 	SET_LABEL(p, swapped_seqin_fields);
978 	swapped_seqin_fields += 8;
979 	/* Label the second word after JD */
980 	SET_LABEL(p, swapped_seqin_ptr);
981 	swapped_seqin_ptr += 9;
982 
983 	PATCH_HDR(p, phdr, hdr);
984 	PATCH_JUMP(p, pkeyjump, keyjump);
985 	PATCH_JUMP(p, swapped_seqin_ptr_jump, swapped_seqin_ptr);
986 	PATCH_MOVE(p, move_outlen, outptr);
987 	PATCH_MOVE(p, move_seqout_ptr, shd_ptr);
988 	PATCH_MOVE(p, write_swapped_seqin_ptr, swapped_seqin_fields);
989 	return PROGRAM_FINALIZE(p);
990 }
991 
992 /**
993  * cnstr_shdsc_ipsec_decap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
994  *     AES-XCBC-MAC-96 ESP decapsulation shared descriptor.
995  * @descbuf: pointer to buffer used for descriptor construction
996  * @share: sharing type of shared descriptor
997  * @pdb: pointer to the PDB to be used with this descriptor
998  *       This structure will be copied inline to the descriptor under
999  *       construction. No error checking will be made. Refer to the
1000  *       block guide for a details of the encapsulation PDB.
1001  * @cipherdata: pointer to block cipher transform definitions
1002  *              Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
1003  * @authdata: pointer to authentication transform definitions
1004  *            Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
1005  *
1006  * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
1007  * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
1008  * Outer/Transport IP Header is present in the decapsulation input packet.
1009  * The descriptor computes the AES-XCBC-MAC-96 to check if the received ICV
1010  * is correct, rereads the input packet to compute the MD5 ICV, overwrites
1011  * the XCBC ICV, and then sends the modified input packet to the
1012  * DES-CBC/3DES-CBC & HMAC-MD5-96 IPsec.
1013  * The descriptor uses all the benefits of the built-in protocol by computing
1014  * the IPsec ESP with a hardware supported algorithms combination
1015  * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
1016  * was chosen in order to speed up the computational time for this intermediate
1017  * step.
1018  * Warning: The user must allocate at least 32 bytes for the authentication key
1019  * (in order to use it also with HMAC-MD5-96),even when using a shorter key
1020  * for the AES-XCBC-MAC-96.
1021  *
1022  * Return: size of descriptor written in words or negative number on error
1023  */
1024 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)1025 cnstr_shdsc_ipsec_decap_des_aes_xcbc(uint32_t *descbuf,
1026 				     enum rta_share_type share,
1027 				     struct ipsec_decap_pdb *pdb,
1028 				     struct alginfo *cipherdata,
1029 				     struct alginfo *authdata)
1030 {
1031 	struct program prg;
1032 	struct program *p = &prg;
1033 	uint32_t ip_hdr_len = (pdb->options & PDBHDRLEN_MASK) >>
1034 				PDBHDRLEN_ESP_DECAP_SHIFT;
1035 
1036 	LABEL(hdr);
1037 	LABEL(jump_cmd);
1038 	LABEL(keyjump);
1039 	LABEL(outlen);
1040 	LABEL(seqin_ptr);
1041 	LABEL(seqout_ptr);
1042 	LABEL(swapped_seqout_fields);
1043 	LABEL(swapped_seqout_ptr);
1044 	REFERENCE(seqout_ptr_jump);
1045 	REFERENCE(phdr);
1046 	REFERENCE(pkeyjump);
1047 	REFERENCE(move_jump);
1048 	REFERENCE(move_jump_back);
1049 	REFERENCE(move_seqin_ptr);
1050 	REFERENCE(swapped_seqout_ptr_jump);
1051 	REFERENCE(write_swapped_seqout_ptr);
1052 
1053 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
1054 	phdr = SHR_HDR(p, share, hdr, 0);
1055 	__rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
1056 	SET_LABEL(p, hdr);
1057 	pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
1058 	/*
1059 	 * Hard-coded KEY arguments. The descriptor uses all the benefits of
1060 	 * the built-in protocol by computing the IPsec ESP with a hardware
1061 	 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
1062 	 * The HMAC-MD5 authentication algorithm was chosen with
1063 	 * the keys options from bellow in order to speed up the computational
1064 	 * time for this intermediate step.
1065 	 * Warning: The user must allocate at least 32 bytes for
1066 	 * the authentication key (in order to use it also with HMAC-MD5-96),
1067 	 * even when using a shorter key for the AES-XCBC-MAC-96.
1068 	 */
1069 	KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
1070 	SET_LABEL(p, keyjump);
1071 	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
1072 	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
1073 	     0);
1074 	KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
1075 	    INLINE_KEY(authdata));
1076 	MATHB(p, SEQINSZ, SUB,
1077 	      (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), MATH0, 4,
1078 	      IMMED2);
1079 	MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
1080 	ALG_OPERATION(p, OP_ALG_ALGSEL_MD5, OP_ALG_AAI_HMAC_PRECOMP,
1081 		      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
1082 	ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
1083 		      OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
1084 	SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
1085 	SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1);
1086 	SEQFIFOLOAD(p, ICV1, IPSEC_ICV_MD5_TRUNC_SIZE, FLUSH1 | LAST1);
1087 	/* Swap SEQOUTPTR to SEQINPTR. */
1088 	move_seqin_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
1089 	MATHB(p, MATH1, OR, CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR, MATH1, 8,
1090 	      IFB | IMMED2);
1091 /*
1092  * TODO: RTA currently doesn't support creating a LOAD command
1093  * with another command as IMM.
1094  * To be changed when proper support is added in RTA.
1095  */
1096 	LOAD(p, 0xA00000e1, MATH3, 4, 4, IMMED);
1097 	MATHB(p, MATH3, SHLD, MATH3, MATH3,  8, 0);
1098 	write_swapped_seqout_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
1099 					IMMED);
1100 	swapped_seqout_ptr_jump = JUMP(p, swapped_seqout_ptr, LOCAL_JUMP,
1101 				       ALL_TRUE, 0);
1102 /*
1103  * TODO: To be changed when proper support is added in RTA (can't load
1104  * a command that is also written by RTA).
1105  * Change when proper RTA support is added.
1106  */
1107 	SET_LABEL(p, jump_cmd);
1108 	WORD(p, 0xA00000f3);
1109 	SEQINPTR(p, 0, 65535, RTO);
1110 	MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
1111 	MATHB(p, MATH0, ADD, ip_hdr_len, VSEQOUTSZ, 4, IMMED2);
1112 	move_jump = MOVE(p, DESCBUF, 0, OFIFO, 0, 8, WAITCOMP | IMMED);
1113 	move_jump_back = MOVE(p, OFIFO, 0, DESCBUF, 0, 8, IMMED);
1114 	SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
1115 	SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
1116 	SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
1117 	SEQSTORE(p, CONTEXT2, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
1118 	seqout_ptr_jump = JUMP(p, seqout_ptr, LOCAL_JUMP, ALL_TRUE, CALM);
1119 
1120 	LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
1121 	     CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_CLR_C2MODE |
1122 	     CLRW_CLR_C2DATAS | CLRW_CLR_C2CTX | CLRW_RESET_CLS1_CHA, CLRW, 0,
1123 	     4, 0);
1124 	SEQINPTR(p, 0, 65535, RTO);
1125 	MATHB(p, MATH0, ADD,
1126 	      (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), SEQINSZ, 4,
1127 	      IMMED2);
1128 	KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1129 	    cipherdata->keylen, INLINE_KEY(cipherdata));
1130 	PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL, OP_PCLID_IPSEC,
1131 		 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
1132 /*
1133  * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
1134  * To be changed when proper support is added in RTA.
1135  */
1136 	/* Label the SEQ OUT PTR */
1137 	SET_LABEL(p, seqout_ptr);
1138 	seqout_ptr += 2;
1139 	/* Label the Output Length */
1140 	SET_LABEL(p, outlen);
1141 	outlen += 4;
1142 	/* Label the SEQ IN PTR */
1143 	SET_LABEL(p, seqin_ptr);
1144 	seqin_ptr += 5;
1145 	/* Label the first word after JD */
1146 	SET_LABEL(p, swapped_seqout_fields);
1147 	swapped_seqout_fields += 8;
1148 	/* Label the second word after JD */
1149 	SET_LABEL(p, swapped_seqout_ptr);
1150 	swapped_seqout_ptr += 9;
1151 
1152 	PATCH_HDR(p, phdr, hdr);
1153 	PATCH_JUMP(p, pkeyjump, keyjump);
1154 	PATCH_JUMP(p, seqout_ptr_jump, seqout_ptr);
1155 	PATCH_JUMP(p, swapped_seqout_ptr_jump, swapped_seqout_ptr);
1156 	PATCH_MOVE(p, move_jump, jump_cmd);
1157 	PATCH_MOVE(p, move_jump_back, seqin_ptr);
1158 	PATCH_MOVE(p, move_seqin_ptr, outlen);
1159 	PATCH_MOVE(p, write_swapped_seqout_ptr, swapped_seqout_fields);
1160 	return PROGRAM_FINALIZE(p);
1161 }
1162 
1163 /**
1164  * IPSEC_NEW_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor length
1165  *
1166  * Accounts only for the "base" commands and is intended to be used by upper
1167  * layers to determine whether Outer IP Header and/or keys can be inlined or
1168  * not. To be used as first parameter of rta_inline_query().
1169  */
1170 #define IPSEC_NEW_ENC_BASE_DESC_LEN	(12 * CAAM_CMD_SZ + \
1171 					 sizeof(struct ipsec_encap_pdb))
1172 
1173 /**
1174  * IPSEC_NEW_NULL_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor
1175  *                                    length for the case of
1176  *                                    NULL encryption / authentication
1177  *
1178  * Accounts only for the "base" commands and is intended to be used by upper
1179  * layers to determine whether Outer IP Header and/or key can be inlined or
1180  * not. To be used as first parameter of rta_inline_query().
1181  */
1182 #define IPSEC_NEW_NULL_ENC_BASE_DESC_LEN	(11 * CAAM_CMD_SZ + \
1183 						 sizeof(struct ipsec_encap_pdb))
1184 
1185 /**
1186  * cnstr_shdsc_ipsec_new_encap -  IPSec new mode ESP encapsulation
1187  *     protocol-level shared descriptor.
1188  * @descbuf: pointer to buffer used for descriptor construction
1189  * @ps: if 36/40bit addressing is desired, this parameter must be true
1190  * @swap: must be true when core endianness doesn't match SEC endianness
1191  * @share: sharing type of shared descriptor
1192  * @pdb: pointer to the PDB to be used with this descriptor
1193  *       This structure will be copied inline to the descriptor under
1194  *       construction. No error checking will be made. Refer to the
1195  *       block guide for details about the encapsulation PDB.
1196  * @opt_ip_hdr:  pointer to Optional IP Header
1197  *     -if OIHI = PDBOPTS_ESP_OIHI_PDB_INL, opt_ip_hdr points to the buffer to
1198  *     be inlined in the PDB. Number of bytes (buffer size) copied is provided
1199  *     in pdb->ip_hdr_len.
1200  *     -if OIHI = PDBOPTS_ESP_OIHI_PDB_REF, opt_ip_hdr points to the address of
1201  *     the Optional IP Header. The address will be inlined in the PDB verbatim.
1202  *     -for other values of OIHI options field, opt_ip_hdr is not used.
1203  * @cipherdata: pointer to block cipher transform definitions
1204  *              Valid algorithm values - one of OP_PCL_IPSEC_*
1205  * @authdata: pointer to authentication transform definitions.
1206  *            If an authentication key is required by the protocol, a "normal"
1207  *            key must be provided; DKP (Derived Key Protocol) will be used to
1208  *            compute MDHA on the fly in HW.
1209  *            Valid algorithm values - one of OP_PCL_IPSEC_*
1210  *
1211  * Note: L2 header copy functionality is implemented assuming that bits 14
1212  * (currently reserved) and 16-23 (part of Outer IP Header Material Length)
1213  * in DPOVRD register are not used (which is usually the case when L3 header
1214  * is provided in PDB).
1215  * When DPOVRD[14] is set, frame starts with an L2 header; in this case, the
1216  * L2 header length is found at DPOVRD[23:16]. SEC uses this length to copy
1217  * the header and then it deletes DPOVRD[23:16] (so there is no side effect
1218  * when later running IPsec protocol).
1219  *
1220  * Return: size of descriptor written in words or negative number on error
1221  */
1222 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)1223 cnstr_shdsc_ipsec_new_encap(uint32_t *descbuf, bool ps,
1224 			    bool swap,
1225 			    enum rta_share_type share,
1226 			    struct ipsec_encap_pdb *pdb,
1227 			    uint8_t *opt_ip_hdr,
1228 			    struct alginfo *cipherdata,
1229 			    struct alginfo *authdata)
1230 {
1231 	struct program prg;
1232 	struct program *p = &prg;
1233 
1234 	LABEL(keyjmp);
1235 	REFERENCE(pkeyjmp);
1236 	LABEL(hdr);
1237 	REFERENCE(phdr);
1238 	LABEL(l2copy);
1239 	REFERENCE(pl2copy);
1240 
1241 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
1242 	if (swap)
1243 		PROGRAM_SET_BSWAP(p);
1244 	if (ps)
1245 		PROGRAM_SET_36BIT_ADDR(p);
1246 	phdr = SHR_HDR(p, share, hdr, 0);
1247 
1248 	__rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
1249 
1250 	switch (pdb->options & PDBOPTS_ESP_OIHI_MASK) {
1251 	case PDBOPTS_ESP_OIHI_PDB_INL:
1252 		COPY_DATA(p, opt_ip_hdr, pdb->ip_hdr_len);
1253 		break;
1254 	case PDBOPTS_ESP_OIHI_PDB_REF:
1255 		if (ps)
1256 			COPY_DATA(p, opt_ip_hdr, 8);
1257 		else
1258 			COPY_DATA(p, opt_ip_hdr, 4);
1259 		break;
1260 	default:
1261 		break;
1262 	}
1263 	SET_LABEL(p, hdr);
1264 
1265 	MATHB(p, DPOVRD, AND, IPSEC_N_ENCAP_DPOVRD_L2_COPY, NONE, 4, IMMED2);
1266 	pl2copy = JUMP(p, l2copy, LOCAL_JUMP, ALL_TRUE, MATH_Z);
1267 	MATHI(p, DPOVRD, RSHIFT, IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT, VSEQOUTSZ,
1268 	      1, 0);
1269 	MATHB(p, DPOVRD, AND, ~IPSEC_N_ENCAP_DPOVRD_L2_LEN_MASK, DPOVRD, 4,
1270 	      IMMED2);
1271 	/* TODO: CLASS2 corresponds to AUX=2'b10; add more intuitive defines */
1272 	SEQFIFOSTORE(p, METADATA, 0, 0, CLASS2 | VLF);
1273 	SET_LABEL(p, l2copy);
1274 
1275 	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1276 	if (authdata->keylen)
1277 		__gen_auth_key(p, authdata);
1278 	if (cipherdata->keylen)
1279 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1280 		    cipherdata->keylen, INLINE_KEY(cipherdata));
1281 	SET_LABEL(p, keyjmp);
1282 	PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
1283 		 OP_PCLID_IPSEC_NEW,
1284 		 (uint16_t)(cipherdata->algtype | authdata->algtype));
1285 	PATCH_JUMP(p, pl2copy, l2copy);
1286 	PATCH_JUMP(p, pkeyjmp, keyjmp);
1287 	PATCH_HDR(p, phdr, hdr);
1288 	return PROGRAM_FINALIZE(p);
1289 }
1290 
1291 /**
1292  * IPSEC_NEW_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor length
1293  *
1294  * Accounts only for the "base" commands and is intended to be used by upper
1295  * layers to determine whether keys can be inlined or not. To be used as first
1296  * parameter of rta_inline_query().
1297  */
1298 #define IPSEC_NEW_DEC_BASE_DESC_LEN	(5 * CAAM_CMD_SZ + \
1299 					 sizeof(struct ipsec_decap_pdb))
1300 
1301 /**
1302  * IPSEC_NEW_NULL_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor
1303  *                                    length for the case of
1304  *                                    NULL decryption / authentication
1305  *
1306  * Accounts only for the "base" commands and is intended to be used by upper
1307  * layers to determine whether key can be inlined or not. To be used as first
1308  * parameter of rta_inline_query().
1309  */
1310 #define IPSEC_NEW_NULL_DEC_BASE_DESC_LEN	(4 * CAAM_CMD_SZ + \
1311 						 sizeof(struct ipsec_decap_pdb))
1312 
1313 /**
1314  * cnstr_shdsc_ipsec_new_decap - IPSec new mode ESP decapsulation protocol-level
1315  *     shared descriptor.
1316  * @descbuf: pointer to buffer used for descriptor construction
1317  * @ps: if 36/40bit addressing is desired, this parameter must be true
1318  * @swap: must be true when core endianness doesn't match SEC endianness
1319  * @share: sharing type of shared descriptor
1320  * @pdb: pointer to the PDB to be used with this descriptor
1321  *       This structure will be copied inline to the descriptor under
1322  *       construction. No error checking will be made. Refer to the
1323  *       block guide for details about the decapsulation PDB.
1324  * @cipherdata: pointer to block cipher transform definitions
1325  *              Valid algorithm values 0 one of OP_PCL_IPSEC_*
1326  * @authdata: pointer to authentication transform definitions.
1327  *            If an authentication key is required by the protocol, a "normal"
1328  *            key must be provided; DKP (Derived Key Protocol) will be used to
1329  *            compute MDHA on the fly in HW.
1330  *            Valid algorithm values - one of OP_PCL_IPSEC_*
1331  *
1332  * Return: size of descriptor written in words or negative number on error
1333  */
1334 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)1335 cnstr_shdsc_ipsec_new_decap(uint32_t *descbuf, bool ps,
1336 			    bool swap,
1337 			    enum rta_share_type share,
1338 			    struct ipsec_decap_pdb *pdb,
1339 			    struct alginfo *cipherdata,
1340 			    struct alginfo *authdata)
1341 {
1342 	struct program prg;
1343 	struct program *p = &prg;
1344 
1345 	LABEL(keyjmp);
1346 	REFERENCE(pkeyjmp);
1347 	LABEL(hdr);
1348 	REFERENCE(phdr);
1349 
1350 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
1351 	if (swap)
1352 		PROGRAM_SET_BSWAP(p);
1353 	if (ps)
1354 		PROGRAM_SET_36BIT_ADDR(p);
1355 	phdr = SHR_HDR(p, share, hdr, 0);
1356 	__rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
1357 	SET_LABEL(p, hdr);
1358 	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1359 	if (authdata->keylen)
1360 		__gen_auth_key(p, authdata);
1361 	if (cipherdata->keylen)
1362 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1363 		    cipherdata->keylen, INLINE_KEY(cipherdata));
1364 	SET_LABEL(p, keyjmp);
1365 	PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
1366 		 OP_PCLID_IPSEC_NEW,
1367 		 (uint16_t)(cipherdata->algtype | authdata->algtype));
1368 	PATCH_JUMP(p, pkeyjmp, keyjmp);
1369 	PATCH_HDR(p, phdr, hdr);
1370 	return PROGRAM_FINALIZE(p);
1371 }
1372 
1373 /**
1374  * IPSEC_AUTH_VAR_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1375  *				for the case of variable-length authentication
1376  *				only data.
1377  *				Note: Only for SoCs with SEC_ERA >= 3.
1378  *
1379  * Accounts only for the "base" commands and is intended to be used by upper
1380  * layers to determine whether keys can be inlined or not. To be used as first
1381  * parameter of rta_inline_query().
1382  */
1383 #define IPSEC_AUTH_VAR_BASE_DESC_LEN	(27 * CAAM_CMD_SZ)
1384 
1385 /**
1386  * IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor
1387  *                              length for variable-length authentication only
1388  *                              data.
1389  *                              Note: Only for SoCs with SEC_ERA >= 3.
1390  *
1391  * Accounts only for the "base" commands and is intended to be used by upper
1392  * layers to determine whether key can be inlined or not. To be used as first
1393  * parameter of rta_inline_query().
1394  */
1395 #define IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN	\
1396 				(IPSEC_AUTH_VAR_BASE_DESC_LEN + CAAM_CMD_SZ)
1397 
1398 /**
1399  * IPSEC_AUTH_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1400  *
1401  * Accounts only for the "base" commands and is intended to be used by upper
1402  * layers to determine whether key can be inlined or not. To be used as first
1403  * parameter of rta_inline_query().
1404  */
1405 #define IPSEC_AUTH_BASE_DESC_LEN	(19 * CAAM_CMD_SZ)
1406 
1407 /**
1408  * IPSEC_AUTH_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor length
1409  *
1410  * Accounts only for the "base" commands and is intended to be used by upper
1411  * layers to determine whether key can be inlined or not. To be used as first
1412  * parameter of rta_inline_query().
1413  */
1414 #define IPSEC_AUTH_AES_DEC_BASE_DESC_LEN	(IPSEC_AUTH_BASE_DESC_LEN + \
1415 						CAAM_CMD_SZ)
1416 
1417 /**
1418  * cnstr_shdsc_authenc - authenc-like descriptor
1419  * @descbuf: pointer to buffer used for descriptor construction
1420  * @ps: if 36/40bit addressing is desired, this parameter must be true
1421  * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
1422  * @share: sharing type of shared descriptor
1423  * @cipherdata: pointer to block cipher transform definitions.
1424  *              Valid algorithm values one of OP_ALG_ALGSEL_* {DES, 3DES, AES}
1425  *              Valid modes for:
1426  *                  AES: OP_ALG_AAI_* {CBC, CTR}
1427  *                  DES, 3DES: OP_ALG_AAI_CBC
1428  * @authdata: pointer to authentication transform definitions.
1429  *            Valid algorithm values - one of OP_ALG_ALGSEL_* {MD5, SHA1,
1430  *            SHA224, SHA256, SHA384, SHA512}
1431  * Note: The key for authentication is supposed to be given as plain text.
1432  * Note: There's no support for keys longer than the block size of the
1433  *       underlying hash function, according to the selected algorithm.
1434  *
1435  * @ivlen: length of the IV to be read from the input frame, before any data
1436  *         to be processed
1437  *
1438  * @trunc_len: the length of the ICV to be written to the output frame. If 0,
1439  *             then the corresponding length of the digest, according to the
1440  *             selected algorithm shall be used.
1441  * @dir: Protocol direction, encapsulation or decapsulation (DIR_ENC/DIR_DEC)
1442  *
1443  * Note: Here's how the input frame needs to be formatted so that the processing
1444  *       will be done correctly:
1445  * For encapsulation:
1446  *     Input:
1447  * +----+----------------+-----------------------------------------------+
1448  * | IV | Auth-only head | Padded data to be auth & Enc | Auth-only tail |
1449  * +----+----------------+-----------------------------------------------+
1450  *     Output:
1451  * +--------------------------------------+
1452  * | Authenticated & Encrypted data | ICV |
1453  * +--------------------------------+-----+
1454  *
1455  * For decapsulation:
1456  *     Input:
1457  * +----+----------------+-----------------+----------------------+
1458  * | IV | Auth-only head | Auth & Enc data | Auth-only tail | ICV |
1459  * +----+----------------+-----------------+----------------------+
1460  *     Output:
1461  * +----+---------------------------+
1462  * | Decrypted & authenticated data |
1463  * +----+---------------------------+
1464  *
1465  * Note: This descriptor can use per-packet commands, encoded as below in the
1466  *       DPOVRD register:
1467  * 32    28               16	         1
1468  * +------+------------------------------+
1469  * | 0x8  | auth_tail_len | auth_hdr_len |
1470  * +------+------------------------------+
1471  *
1472  * This mechanism is available only for SoCs having SEC ERA >= 3. In other
1473  * words, this will not work for P4080TO2
1474  *
1475  * Note: The descriptor does not add any kind of padding to the input data,
1476  *       so the upper layer needs to ensure that the data is padded properly,
1477  *       according to the selected cipher. Failure to do so will result in
1478  *       the descriptor failing with a data-size error.
1479  *
1480  * Return: size of descriptor written in words or negative number on error
1481  */
1482 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)1483 cnstr_shdsc_authenc(uint32_t *descbuf, bool ps, bool swap,
1484 		    enum rta_share_type share,
1485 		    struct alginfo *cipherdata,
1486 		    struct alginfo *authdata,
1487 		    uint16_t ivlen,
1488 		    uint8_t trunc_len, uint8_t dir)
1489 {
1490 	struct program prg;
1491 	struct program *p = &prg;
1492 	const bool need_dk = (dir == DIR_DEC) &&
1493 			     (cipherdata->algtype == OP_ALG_ALGSEL_AES) &&
1494 			     (cipherdata->algmode == OP_ALG_AAI_CBC);
1495 	int data_type;
1496 
1497 	LABEL(keyjmp);
1498 	LABEL(skipkeys);
1499 	LABEL(proc_icv);
1500 	LABEL(no_auth_tail);
1501 	REFERENCE(pkeyjmp);
1502 	REFERENCE(pskipkeys);
1503 	REFERENCE(p_proc_icv);
1504 	REFERENCE(p_no_auth_tail);
1505 
1506 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
1507 
1508 	if (swap)
1509 		PROGRAM_SET_BSWAP(p);
1510 	if (ps)
1511 		PROGRAM_SET_36BIT_ADDR(p);
1512 
1513 	/*
1514 	 * Since we currently assume that key length is equal to hash digest
1515 	 * size, it's ok to truncate keylen value.
1516 	 */
1517 	trunc_len = trunc_len && (trunc_len < authdata->keylen) ?
1518 			trunc_len : (uint8_t)authdata->keylen;
1519 
1520 	SHR_HDR(p, share, 1, SC);
1521 
1522 	/* Collect the (auth_tail || auth_hdr) len from DPOVRD */
1523 	MATHB(p, DPOVRD, ADD, 0x80000000, MATH2, 4, IMMED2);
1524 
1525 	/* Get auth_hdr len in MATH0 */
1526 	MATHB(p, MATH2, AND, 0xFFFF, MATH0, 4, IMMED2);
1527 
1528 	/* Get auth_tail len in MATH2 */
1529 	MATHB(p, MATH2, AND, 0xFFF0000, MATH2, 4, IMMED2);
1530 	MATHI(p, MATH2, RSHIFT, 16, MATH2, 4, IMMED2);
1531 
1532 	pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1533 
1534 	KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1535 	    INLINE_KEY(authdata));
1536 
1537 	/* Insert Key */
1538 	KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1539 	    cipherdata->keylen, INLINE_KEY(cipherdata));
1540 
1541 	/* Do operation */
1542 	ALG_OPERATION(p, authdata->algtype, authdata->algmode,
1543 		      OP_ALG_AS_INITFINAL,
1544 		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1545 		      dir);
1546 
1547 	if (need_dk)
1548 		ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode,
1549 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1550 	pskipkeys = JUMP(p, skipkeys, LOCAL_JUMP, ALL_TRUE, 0);
1551 
1552 	SET_LABEL(p, keyjmp);
1553 
1554 	if (authdata->algmode == OP_ALG_AAI_HMAC)
1555 		ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
1556 		      OP_ALG_AS_INITFINAL,
1557 		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1558 		      dir);
1559 	else
1560 		ALG_OPERATION(p, authdata->algtype, authdata->algmode,
1561 		      OP_ALG_AS_INITFINAL,
1562 		      dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1563 		      dir);
1564 
1565 	if (need_dk) {
1566 		ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode |
1567 			      OP_ALG_AAI_DK, OP_ALG_AS_INITFINAL,
1568 			      ICV_CHECK_DISABLE, dir);
1569 		SET_LABEL(p, skipkeys);
1570 	} else {
1571 		SET_LABEL(p, skipkeys);
1572 		ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
1573 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1574 	}
1575 
1576 	/* Read IV */
1577 	if (cipherdata->algmode == OP_ALG_AAI_CTR)
1578 		SEQLOAD(p, CONTEXT1, 16, ivlen, 0);
1579 	else
1580 		SEQLOAD(p, CONTEXT1, 0, ivlen, 0);
1581 
1582 	/*
1583 	 * authenticate auth_hdr data
1584 	 */
1585 	MATHB(p, MATH0, ADD, ZERO, VSEQINSZ, 4, 0);
1586 	SEQFIFOLOAD(p, MSG2, 0, VLF);
1587 
1588 	/*
1589 	 * Prepare the length of the data to be both encrypted/decrypted
1590 	 * and authenticated/checked
1591 	 */
1592 	MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
1593 	if (dir == DIR_DEC) {
1594 		MATHB(p, VSEQINSZ, SUB, trunc_len, VSEQINSZ, 4, IMMED2);
1595 		data_type = MSGINSNOOP;
1596 	} else {
1597 		data_type = MSGOUTSNOOP;
1598 	}
1599 
1600 	MATHB(p, VSEQINSZ, ADD, ZERO, VSEQOUTSZ, 4, 0);
1601 
1602 	/* Prepare for writing the output frame */
1603 	SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1604 
1605 
1606 	/* Check if there is no auth-tail */
1607 	MATHB(p, MATH2, ADD, ZERO, MATH2, 4, 0);
1608 	p_no_auth_tail = JUMP(p, no_auth_tail, LOCAL_JUMP, ALL_TRUE, MATH_Z);
1609 
1610 	/*
1611 	 * Read input plain/cipher text, encrypt/decrypt & auth & write
1612 	 * to output
1613 	 */
1614 	SEQFIFOLOAD(p, data_type, 0, VLF | LAST1 | FLUSH1);
1615 
1616 	/* Authenticate auth tail */
1617 	MATHB(p, MATH2, ADD, ZERO, VSEQINSZ, 4, 0);
1618 	SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
1619 
1620 	/* Jump to process icv */
1621 	p_proc_icv = JUMP(p, proc_icv, LOCAL_JUMP, ALL_FALSE, MATH_Z);
1622 
1623 	SET_LABEL(p, no_auth_tail);
1624 
1625 	SEQFIFOLOAD(p, data_type, 0, VLF | LAST1 | LAST2 | FLUSH1);
1626 
1627 	SET_LABEL(p, proc_icv);
1628 
1629 	if (dir == DIR_ENC)
1630 		/* Finally, write the ICV */
1631 		SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
1632 	else
1633 		/* Read the ICV to check */
1634 		SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
1635 
1636 	PATCH_JUMP(p, pkeyjmp, keyjmp);
1637 	PATCH_JUMP(p, pskipkeys, skipkeys);
1638 	PATCH_JUMP(p, p_no_auth_tail, no_auth_tail);
1639 	PATCH_JUMP(p, p_proc_icv, proc_icv);
1640 	return PROGRAM_FINALIZE(p);
1641 }
1642 
1643 #endif /* __DESC_IPSEC_H__ */
1644