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