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