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