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