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