New upstream version 18.02
[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  */
526
527 #define IPSEC_DECO_DPOVRD_USE           0x80
528
529 struct ipsec_deco_dpovrd {
530         uint8_t ovrd_ecn;
531         uint8_t ip_hdr_len;
532         uint8_t nh_offset;
533         union {
534                 uint8_t next_header;    /* next header if encap */
535                 uint8_t rsvd;           /* reserved if decap */
536         };
537 };
538
539 struct ipsec_new_encap_deco_dpovrd {
540 #define IPSEC_NEW_ENCAP_DECO_DPOVRD_USE 0x8000
541         uint16_t ovrd_ip_hdr_len;       /* OVRD + outer IP header material
542                                          * length
543                                          */
544 #define IPSEC_NEW_ENCAP_OIMIF           0x80
545         uint8_t oimif_aoipho;           /* OIMIF + actual outer IP header
546                                          * offset
547                                          */
548         uint8_t rsvd;
549 };
550
551 struct ipsec_new_decap_deco_dpovrd {
552         uint8_t ovrd;
553         uint8_t aoipho_hi;              /* upper nibble of actual outer IP
554                                          * header
555                                          */
556         uint16_t aoipho_lo_ip_hdr_len;  /* lower nibble of actual outer IP
557                                          * header + outer IP header material
558                                          */
559 };
560
561 static inline void
562 __gen_auth_key(struct program *program, struct alginfo *authdata)
563 {
564         uint32_t dkp_protid;
565
566         switch (authdata->algtype & OP_PCL_IPSEC_AUTH_MASK) {
567         case OP_PCL_IPSEC_HMAC_MD5_96:
568         case OP_PCL_IPSEC_HMAC_MD5_128:
569                 dkp_protid = OP_PCLID_DKP_MD5;
570                 break;
571         case OP_PCL_IPSEC_HMAC_SHA1_96:
572         case OP_PCL_IPSEC_HMAC_SHA1_160:
573                 dkp_protid = OP_PCLID_DKP_SHA1;
574                 break;
575         case OP_PCL_IPSEC_HMAC_SHA2_256_128:
576                 dkp_protid = OP_PCLID_DKP_SHA256;
577                 break;
578         case OP_PCL_IPSEC_HMAC_SHA2_384_192:
579                 dkp_protid = OP_PCLID_DKP_SHA384;
580                 break;
581         case OP_PCL_IPSEC_HMAC_SHA2_512_256:
582                 dkp_protid = OP_PCLID_DKP_SHA512;
583                 break;
584         default:
585                 KEY(program, KEY2, authdata->key_enc_flags, authdata->key,
586                     authdata->keylen, INLINE_KEY(authdata));
587                 return;
588         }
589
590         if (authdata->key_type == RTA_DATA_PTR)
591                 DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_PTR,
592                              OP_PCL_DKP_DST_PTR, (uint16_t)authdata->keylen,
593                              authdata->key, authdata->key_type);
594         else
595                 DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_IMM,
596                              OP_PCL_DKP_DST_IMM, (uint16_t)authdata->keylen,
597                              authdata->key, authdata->key_type);
598 }
599
600 /**
601  * cnstr_shdsc_ipsec_encap - IPSec ESP encapsulation protocol-level shared
602  *                           descriptor.
603  * @descbuf: pointer to buffer used for descriptor construction
604  * @ps: if 36/40bit addressing is desired, this parameter must be true
605  * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
606  * @pdb: pointer to the PDB to be used with this descriptor
607  *       This structure will be copied inline to the descriptor under
608  *       construction. No error checking will be made. Refer to the
609  *       block guide for a details of the encapsulation PDB.
610  * @cipherdata: pointer to block cipher transform definitions
611  *              Valid algorithm values - one of OP_PCL_IPSEC_*
612  * @authdata: pointer to authentication transform definitions
613  *            If an authentication key is required by the protocol:
614  *            -For SEC Eras 1-5, an MDHA split key must be provided;
615  *            Note that the size of the split key itself must be specified.
616  *            -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
617  *            Key Protocol) will be used to compute MDHA on the fly in HW.
618  *            Valid algorithm values - one of OP_PCL_IPSEC_*
619  *
620  * Return: size of descriptor written in words or negative number on error
621  */
622 static inline int
623 cnstr_shdsc_ipsec_encap(uint32_t *descbuf, bool ps, bool swap,
624                         struct ipsec_encap_pdb *pdb,
625                         struct alginfo *cipherdata,
626                         struct alginfo *authdata)
627 {
628         struct program prg;
629         struct program *p = &prg;
630
631         LABEL(keyjmp);
632         REFERENCE(pkeyjmp);
633         LABEL(hdr);
634         REFERENCE(phdr);
635
636         PROGRAM_CNTXT_INIT(p, descbuf, 0);
637         if (swap)
638                 PROGRAM_SET_BSWAP(p);
639         if (ps)
640                 PROGRAM_SET_36BIT_ADDR(p);
641         phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
642         __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
643         COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
644         SET_LABEL(p, hdr);
645         pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
646         if (authdata->keylen) {
647                 if (rta_sec_era < RTA_SEC_ERA_6)
648                         KEY(p, MDHA_SPLIT_KEY, authdata->key_enc_flags,
649                             authdata->key, authdata->keylen,
650                             INLINE_KEY(authdata));
651                 else
652                         __gen_auth_key(p, authdata);
653         }
654         if (cipherdata->keylen)
655                 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
656                     cipherdata->keylen, INLINE_KEY(cipherdata));
657         SET_LABEL(p, keyjmp);
658         PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
659                  OP_PCLID_IPSEC,
660                  (uint16_t)(cipherdata->algtype | authdata->algtype));
661         PATCH_JUMP(p, pkeyjmp, keyjmp);
662         PATCH_HDR(p, phdr, hdr);
663         return PROGRAM_FINALIZE(p);
664 }
665
666 /**
667  * cnstr_shdsc_ipsec_decap - IPSec ESP decapsulation protocol-level shared
668  *                           descriptor.
669  * @descbuf: pointer to buffer used for descriptor construction
670  * @ps: if 36/40bit addressing is desired, this parameter must be true
671  * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
672  * @pdb: pointer to the PDB to be used with this descriptor
673  *       This structure will be copied inline to the descriptor under
674  *       construction. No error checking will be made. Refer to the
675  *       block guide for details about the decapsulation PDB.
676  * @cipherdata: pointer to block cipher transform definitions.
677  *              Valid algorithm values - one of OP_PCL_IPSEC_*
678  * @authdata: pointer to authentication transform definitions
679  *            If an authentication key is required by the protocol:
680  *            -For SEC Eras 1-5, an MDHA split key must be provided;
681  *            Note that the size of the split key itself must be specified.
682  *            -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
683  *            Key Protocol) will be used to compute MDHA on the fly in HW.
684  *            Valid algorithm values - one of OP_PCL_IPSEC_*
685  *
686  * Return: size of descriptor written in words or negative number on error
687  */
688 static inline int
689 cnstr_shdsc_ipsec_decap(uint32_t *descbuf, bool ps, bool swap,
690                         struct ipsec_decap_pdb *pdb,
691                         struct alginfo *cipherdata,
692                         struct alginfo *authdata)
693 {
694         struct program prg;
695         struct program *p = &prg;
696
697         LABEL(keyjmp);
698         REFERENCE(pkeyjmp);
699         LABEL(hdr);
700         REFERENCE(phdr);
701
702         PROGRAM_CNTXT_INIT(p, descbuf, 0);
703         if (swap)
704                 PROGRAM_SET_BSWAP(p);
705         if (ps)
706                 PROGRAM_SET_36BIT_ADDR(p);
707         phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
708         __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
709         SET_LABEL(p, hdr);
710         pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
711         if (authdata->keylen) {
712                 if (rta_sec_era < RTA_SEC_ERA_6)
713                         KEY(p, MDHA_SPLIT_KEY, authdata->key_enc_flags,
714                             authdata->key, authdata->keylen,
715                             INLINE_KEY(authdata));
716                 else
717                         __gen_auth_key(p, authdata);
718         }
719         if (cipherdata->keylen)
720                 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
721                     cipherdata->keylen, INLINE_KEY(cipherdata));
722         SET_LABEL(p, keyjmp);
723         PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
724                  OP_PCLID_IPSEC,
725                  (uint16_t)(cipherdata->algtype | authdata->algtype));
726         PATCH_JUMP(p, pkeyjmp, keyjmp);
727         PATCH_HDR(p, phdr, hdr);
728         return PROGRAM_FINALIZE(p);
729 }
730
731 /**
732  * cnstr_shdsc_ipsec_encap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
733  *     AES-XCBC-MAC-96 ESP encapsulation shared descriptor.
734  * @descbuf: pointer to buffer used for descriptor construction
735  * @pdb: pointer to the PDB to be used with this descriptor
736  *       This structure will be copied inline to the descriptor under
737  *       construction. No error checking will be made. Refer to the
738  *       block guide for a details of the encapsulation PDB.
739  * @cipherdata: pointer to block cipher transform definitions
740  *              Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
741  * @authdata: pointer to authentication transform definitions
742  *            Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
743  *
744  * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
745  * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
746  * Outer/Transport IP Header is present in the encapsulation output packet.
747  * The descriptor performs DES-CBC/3DES-CBC & HMAC-MD5-96 and then rereads
748  * the input packet to do the AES-XCBC-MAC-96 calculation and to overwrite
749  * the MD5 ICV.
750  * The descriptor uses all the benefits of the built-in protocol by computing
751  * the IPsec ESP with a hardware supported algorithms combination
752  * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
753  * was chosen in order to speed up the computational time for this intermediate
754  * step.
755  * Warning: The user must allocate at least 32 bytes for the authentication key
756  * (in order to use it also with HMAC-MD5-96),even when using a shorter key
757  * for the AES-XCBC-MAC-96.
758  *
759  * Return: size of descriptor written in words or negative number on error
760  */
761 static inline int
762 cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
763                                      struct ipsec_encap_pdb *pdb,
764                                      struct alginfo *cipherdata,
765                                      struct alginfo *authdata)
766 {
767         struct program prg;
768         struct program *p = &prg;
769
770         LABEL(hdr);
771         LABEL(shd_ptr);
772         LABEL(keyjump);
773         LABEL(outptr);
774         LABEL(swapped_seqin_fields);
775         LABEL(swapped_seqin_ptr);
776         REFERENCE(phdr);
777         REFERENCE(pkeyjump);
778         REFERENCE(move_outlen);
779         REFERENCE(move_seqout_ptr);
780         REFERENCE(swapped_seqin_ptr_jump);
781         REFERENCE(write_swapped_seqin_ptr);
782
783         PROGRAM_CNTXT_INIT(p, descbuf, 0);
784         phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
785         __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
786         COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
787         SET_LABEL(p, hdr);
788         pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
789         /*
790          * Hard-coded KEY arguments. The descriptor uses all the benefits of
791          * the built-in protocol by computing the IPsec ESP with a hardware
792          * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
793          * The HMAC-MD5 authentication algorithm was chosen with
794          * the keys options from below in order to speed up the computational
795          * time for this intermediate step.
796          * Warning: The user must allocate at least 32 bytes for
797          * the authentication key (in order to use it also with HMAC-MD5-96),
798          * even when using a shorter key for the AES-XCBC-MAC-96.
799          */
800         KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
801         SET_LABEL(p, keyjump);
802         LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
803              CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
804              IMMED);
805         KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
806             cipherdata->keylen, INLINE_KEY(cipherdata));
807         PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL, OP_PCLID_IPSEC,
808                  (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
809         /* Swap SEQINPTR to SEQOUTPTR. */
810         move_seqout_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
811         MATHB(p, MATH1, AND, ~(CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR), MATH1,
812               8, IFB | IMMED2);
813 /*
814  * TODO: RTA currently doesn't support creating a LOAD command
815  * with another command as IMM.
816  * To be changed when proper support is added in RTA.
817  */
818         LOAD(p, 0xa00000e5, MATH3, 4, 4, IMMED);
819         MATHB(p, MATH3, SHLD, MATH3, MATH3,  8, 0);
820         write_swapped_seqin_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
821                                        IMMED);
822         swapped_seqin_ptr_jump = JUMP(p, swapped_seqin_ptr, LOCAL_JUMP,
823                                       ALL_TRUE, 0);
824         LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
825              CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
826              0);
827         SEQOUTPTR(p, 0, 65535, RTO);
828         move_outlen = MOVE(p, DESCBUF, 0, MATH0, 4, 8, WAITCOMP | IMMED);
829         MATHB(p, MATH0, SUB,
830               (uint64_t)(pdb->ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE),
831               VSEQINSZ, 4, IMMED2);
832         MATHB(p, MATH0, SUB, IPSEC_ICV_MD5_TRUNC_SIZE, VSEQOUTSZ, 4, IMMED2);
833         KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
834             0);
835         ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
836                       OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
837         SEQFIFOLOAD(p, SKIP, pdb->ip_hdr_len, 0);
838         SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1 | LAST1);
839         SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
840         SEQSTORE(p, CONTEXT1, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
841 /*
842  * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
843  * To be changed when proper support is added in RTA.
844  */
845         /* Label the Shared Descriptor Pointer */
846         SET_LABEL(p, shd_ptr);
847         shd_ptr += 1;
848         /* Label the Output Pointer */
849         SET_LABEL(p, outptr);
850         outptr += 3;
851         /* Label the first word after JD */
852         SET_LABEL(p, swapped_seqin_fields);
853         swapped_seqin_fields += 8;
854         /* Label the second word after JD */
855         SET_LABEL(p, swapped_seqin_ptr);
856         swapped_seqin_ptr += 9;
857
858         PATCH_HDR(p, phdr, hdr);
859         PATCH_JUMP(p, pkeyjump, keyjump);
860         PATCH_JUMP(p, swapped_seqin_ptr_jump, swapped_seqin_ptr);
861         PATCH_MOVE(p, move_outlen, outptr);
862         PATCH_MOVE(p, move_seqout_ptr, shd_ptr);
863         PATCH_MOVE(p, write_swapped_seqin_ptr, swapped_seqin_fields);
864         return PROGRAM_FINALIZE(p);
865 }
866
867 /**
868  * cnstr_shdsc_ipsec_decap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
869  *     AES-XCBC-MAC-96 ESP decapsulation shared descriptor.
870  * @descbuf: pointer to buffer used for descriptor construction
871  * @pdb: pointer to the PDB to be used with this descriptor
872  *       This structure will be copied inline to the descriptor under
873  *       construction. No error checking will be made. Refer to the
874  *       block guide for a details of the encapsulation PDB.
875  * @cipherdata: pointer to block cipher transform definitions
876  *              Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
877  * @authdata: pointer to authentication transform definitions
878  *            Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
879  *
880  * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
881  * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
882  * Outer/Transport IP Header is present in the decapsulation input packet.
883  * The descriptor computes the AES-XCBC-MAC-96 to check if the received ICV
884  * is correct, rereads the input packet to compute the MD5 ICV, overwrites
885  * the XCBC ICV, and then sends the modified input packet to the
886  * DES-CBC/3DES-CBC & HMAC-MD5-96 IPsec.
887  * The descriptor uses all the benefits of the built-in protocol by computing
888  * the IPsec ESP with a hardware supported algorithms combination
889  * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
890  * was chosen in order to speed up the computational time for this intermediate
891  * step.
892  * Warning: The user must allocate at least 32 bytes for the authentication key
893  * (in order to use it also with HMAC-MD5-96),even when using a shorter key
894  * for the AES-XCBC-MAC-96.
895  *
896  * Return: size of descriptor written in words or negative number on error
897  */
898 static inline int
899 cnstr_shdsc_ipsec_decap_des_aes_xcbc(uint32_t *descbuf,
900                                      struct ipsec_decap_pdb *pdb,
901                                      struct alginfo *cipherdata,
902                                      struct alginfo *authdata)
903 {
904         struct program prg;
905         struct program *p = &prg;
906         uint32_t ip_hdr_len = (pdb->options & PDBHDRLEN_MASK) >>
907                                 PDBHDRLEN_ESP_DECAP_SHIFT;
908
909         LABEL(hdr);
910         LABEL(jump_cmd);
911         LABEL(keyjump);
912         LABEL(outlen);
913         LABEL(seqin_ptr);
914         LABEL(seqout_ptr);
915         LABEL(swapped_seqout_fields);
916         LABEL(swapped_seqout_ptr);
917         REFERENCE(seqout_ptr_jump);
918         REFERENCE(phdr);
919         REFERENCE(pkeyjump);
920         REFERENCE(move_jump);
921         REFERENCE(move_jump_back);
922         REFERENCE(move_seqin_ptr);
923         REFERENCE(swapped_seqout_ptr_jump);
924         REFERENCE(write_swapped_seqout_ptr);
925
926         PROGRAM_CNTXT_INIT(p, descbuf, 0);
927         phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
928         __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
929         SET_LABEL(p, hdr);
930         pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
931         /*
932          * Hard-coded KEY arguments. The descriptor uses all the benefits of
933          * the built-in protocol by computing the IPsec ESP with a hardware
934          * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
935          * The HMAC-MD5 authentication algorithm was chosen with
936          * the keys options from bellow in order to speed up the computational
937          * time for this intermediate step.
938          * Warning: The user must allocate at least 32 bytes for
939          * the authentication key (in order to use it also with HMAC-MD5-96),
940          * even when using a shorter key for the AES-XCBC-MAC-96.
941          */
942         KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
943         SET_LABEL(p, keyjump);
944         LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
945              CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
946              0);
947         KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
948             INLINE_KEY(authdata));
949         MATHB(p, SEQINSZ, SUB,
950               (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), MATH0, 4,
951               IMMED2);
952         MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
953         ALG_OPERATION(p, OP_ALG_ALGSEL_MD5, OP_ALG_AAI_HMAC_PRECOMP,
954                       OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
955         ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
956                       OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
957         SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
958         SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1);
959         SEQFIFOLOAD(p, ICV1, IPSEC_ICV_MD5_TRUNC_SIZE, FLUSH1 | LAST1);
960         /* Swap SEQOUTPTR to SEQINPTR. */
961         move_seqin_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
962         MATHB(p, MATH1, OR, CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR, MATH1, 8,
963               IFB | IMMED2);
964 /*
965  * TODO: RTA currently doesn't support creating a LOAD command
966  * with another command as IMM.
967  * To be changed when proper support is added in RTA.
968  */
969         LOAD(p, 0xA00000e1, MATH3, 4, 4, IMMED);
970         MATHB(p, MATH3, SHLD, MATH3, MATH3,  8, 0);
971         write_swapped_seqout_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
972                                         IMMED);
973         swapped_seqout_ptr_jump = JUMP(p, swapped_seqout_ptr, LOCAL_JUMP,
974                                        ALL_TRUE, 0);
975 /*
976  * TODO: To be changed when proper support is added in RTA (can't load
977  * a command that is also written by RTA).
978  * Change when proper RTA support is added.
979  */
980         SET_LABEL(p, jump_cmd);
981         WORD(p, 0xA00000f3);
982         SEQINPTR(p, 0, 65535, RTO);
983         MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
984         MATHB(p, MATH0, ADD, ip_hdr_len, VSEQOUTSZ, 4, IMMED2);
985         move_jump = MOVE(p, DESCBUF, 0, OFIFO, 0, 8, WAITCOMP | IMMED);
986         move_jump_back = MOVE(p, OFIFO, 0, DESCBUF, 0, 8, IMMED);
987         SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
988         SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
989         SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
990         SEQSTORE(p, CONTEXT2, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
991         seqout_ptr_jump = JUMP(p, seqout_ptr, LOCAL_JUMP, ALL_TRUE, CALM);
992
993         LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
994              CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_CLR_C2MODE |
995              CLRW_CLR_C2DATAS | CLRW_CLR_C2CTX | CLRW_RESET_CLS1_CHA, CLRW, 0,
996              4, 0);
997         SEQINPTR(p, 0, 65535, RTO);
998         MATHB(p, MATH0, ADD,
999               (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), SEQINSZ, 4,
1000               IMMED2);
1001         KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1002             cipherdata->keylen, INLINE_KEY(cipherdata));
1003         PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL, OP_PCLID_IPSEC,
1004                  (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
1005 /*
1006  * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
1007  * To be changed when proper support is added in RTA.
1008  */
1009         /* Label the SEQ OUT PTR */
1010         SET_LABEL(p, seqout_ptr);
1011         seqout_ptr += 2;
1012         /* Label the Output Length */
1013         SET_LABEL(p, outlen);
1014         outlen += 4;
1015         /* Label the SEQ IN PTR */
1016         SET_LABEL(p, seqin_ptr);
1017         seqin_ptr += 5;
1018         /* Label the first word after JD */
1019         SET_LABEL(p, swapped_seqout_fields);
1020         swapped_seqout_fields += 8;
1021         /* Label the second word after JD */
1022         SET_LABEL(p, swapped_seqout_ptr);
1023         swapped_seqout_ptr += 9;
1024
1025         PATCH_HDR(p, phdr, hdr);
1026         PATCH_JUMP(p, pkeyjump, keyjump);
1027         PATCH_JUMP(p, seqout_ptr_jump, seqout_ptr);
1028         PATCH_JUMP(p, swapped_seqout_ptr_jump, swapped_seqout_ptr);
1029         PATCH_MOVE(p, move_jump, jump_cmd);
1030         PATCH_MOVE(p, move_jump_back, seqin_ptr);
1031         PATCH_MOVE(p, move_seqin_ptr, outlen);
1032         PATCH_MOVE(p, write_swapped_seqout_ptr, swapped_seqout_fields);
1033         return PROGRAM_FINALIZE(p);
1034 }
1035
1036 /**
1037  * IPSEC_NEW_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor length
1038  *
1039  * Accounts only for the "base" commands and is intended to be used by upper
1040  * layers to determine whether Outer IP Header and/or keys can be inlined or
1041  * not. To be used as first parameter of rta_inline_query().
1042  */
1043 #define IPSEC_NEW_ENC_BASE_DESC_LEN     (5 * CAAM_CMD_SZ + \
1044                                          sizeof(struct ipsec_encap_pdb))
1045
1046 /**
1047  * IPSEC_NEW_NULL_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor
1048  *                                    length for the case of
1049  *                                    NULL encryption / authentication
1050  *
1051  * Accounts only for the "base" commands and is intended to be used by upper
1052  * layers to determine whether Outer IP Header and/or key can be inlined or
1053  * not. To be used as first parameter of rta_inline_query().
1054  */
1055 #define IPSEC_NEW_NULL_ENC_BASE_DESC_LEN        (4 * CAAM_CMD_SZ + \
1056                                                  sizeof(struct ipsec_encap_pdb))
1057
1058 /**
1059  * cnstr_shdsc_ipsec_new_encap -  IPSec new mode ESP encapsulation
1060  *     protocol-level shared descriptor.
1061  * @descbuf: pointer to buffer used for descriptor construction
1062  * @ps: if 36/40bit addressing is desired, this parameter must be true
1063  * @swap: must be true when core endianness doesn't match SEC endianness
1064  * @pdb: pointer to the PDB to be used with this descriptor
1065  *       This structure will be copied inline to the descriptor under
1066  *       construction. No error checking will be made. Refer to the
1067  *       block guide for details about the encapsulation PDB.
1068  * @opt_ip_hdr:  pointer to Optional IP Header
1069  *     -if OIHI = PDBOPTS_ESP_OIHI_PDB_INL, opt_ip_hdr points to the buffer to
1070  *     be inlined in the PDB. Number of bytes (buffer size) copied is provided
1071  *     in pdb->ip_hdr_len.
1072  *     -if OIHI = PDBOPTS_ESP_OIHI_PDB_REF, opt_ip_hdr points to the address of
1073  *     the Optional IP Header. The address will be inlined in the PDB verbatim.
1074  *     -for other values of OIHI options field, opt_ip_hdr is not used.
1075  * @cipherdata: pointer to block cipher transform definitions
1076  *              Valid algorithm values - one of OP_PCL_IPSEC_*
1077  * @authdata: pointer to authentication transform definitions.
1078  *            If an authentication key is required by the protocol, a "normal"
1079  *            key must be provided; DKP (Derived Key Protocol) will be used to
1080  *            compute MDHA on the fly in HW.
1081  *            Valid algorithm values - one of OP_PCL_IPSEC_*
1082  *
1083  * Return: size of descriptor written in words or negative number on error
1084  */
1085 static inline int
1086 cnstr_shdsc_ipsec_new_encap(uint32_t *descbuf, bool ps,
1087                             bool swap,
1088                             struct ipsec_encap_pdb *pdb,
1089                             uint8_t *opt_ip_hdr,
1090                             struct alginfo *cipherdata,
1091                             struct alginfo *authdata)
1092 {
1093         struct program prg;
1094         struct program *p = &prg;
1095
1096         LABEL(keyjmp);
1097         REFERENCE(pkeyjmp);
1098         LABEL(hdr);
1099         REFERENCE(phdr);
1100
1101         if (rta_sec_era < RTA_SEC_ERA_8) {
1102                 pr_err("IPsec new mode encap: available only for Era %d or above\n",
1103                        USER_SEC_ERA(RTA_SEC_ERA_8));
1104                 return -ENOTSUP;
1105         }
1106
1107         PROGRAM_CNTXT_INIT(p, descbuf, 0);
1108         if (swap)
1109                 PROGRAM_SET_BSWAP(p);
1110         if (ps)
1111                 PROGRAM_SET_36BIT_ADDR(p);
1112         phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
1113
1114         __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
1115
1116         switch (pdb->options & PDBOPTS_ESP_OIHI_MASK) {
1117         case PDBOPTS_ESP_OIHI_PDB_INL:
1118                 COPY_DATA(p, opt_ip_hdr, pdb->ip_hdr_len);
1119                 break;
1120         case PDBOPTS_ESP_OIHI_PDB_REF:
1121                 if (ps)
1122                         COPY_DATA(p, opt_ip_hdr, 8);
1123                 else
1124                         COPY_DATA(p, opt_ip_hdr, 4);
1125                 break;
1126         default:
1127                 break;
1128         }
1129         SET_LABEL(p, hdr);
1130
1131         pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1132         if (authdata->keylen)
1133                 __gen_auth_key(p, authdata);
1134         if (cipherdata->keylen)
1135                 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1136                     cipherdata->keylen, INLINE_KEY(cipherdata));
1137         SET_LABEL(p, keyjmp);
1138         PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
1139                  OP_PCLID_IPSEC_NEW,
1140                  (uint16_t)(cipherdata->algtype | authdata->algtype));
1141         PATCH_JUMP(p, pkeyjmp, keyjmp);
1142         PATCH_HDR(p, phdr, hdr);
1143         return PROGRAM_FINALIZE(p);
1144 }
1145
1146 /**
1147  * IPSEC_NEW_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor length
1148  *
1149  * Accounts only for the "base" commands and is intended to be used by upper
1150  * layers to determine whether keys can be inlined or not. To be used as first
1151  * parameter of rta_inline_query().
1152  */
1153 #define IPSEC_NEW_DEC_BASE_DESC_LEN     (5 * CAAM_CMD_SZ + \
1154                                          sizeof(struct ipsec_decap_pdb))
1155
1156 /**
1157  * IPSEC_NEW_NULL_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor
1158  *                                    length for the case of
1159  *                                    NULL decryption / authentication
1160  *
1161  * Accounts only for the "base" commands and is intended to be used by upper
1162  * layers to determine whether key can be inlined or not. To be used as first
1163  * parameter of rta_inline_query().
1164  */
1165 #define IPSEC_NEW_NULL_DEC_BASE_DESC_LEN        (4 * CAAM_CMD_SZ + \
1166                                                  sizeof(struct ipsec_decap_pdb))
1167
1168 /**
1169  * cnstr_shdsc_ipsec_new_decap - IPSec new mode ESP decapsulation protocol-level
1170  *     shared descriptor.
1171  * @descbuf: pointer to buffer used for descriptor construction
1172  * @ps: if 36/40bit addressing is desired, this parameter must be true
1173  * @swap: must be true when core endianness doesn't match SEC endianness
1174  * @pdb: pointer to the PDB to be used with this descriptor
1175  *       This structure will be copied inline to the descriptor under
1176  *       construction. No error checking will be made. Refer to the
1177  *       block guide for details about the decapsulation PDB.
1178  * @cipherdata: pointer to block cipher transform definitions
1179  *              Valid algorithm values 0 one of OP_PCL_IPSEC_*
1180  * @authdata: pointer to authentication transform definitions.
1181  *            If an authentication key is required by the protocol, a "normal"
1182  *            key must be provided; DKP (Derived Key Protocol) will be used to
1183  *            compute MDHA on the fly in HW.
1184  *            Valid algorithm values - one of OP_PCL_IPSEC_*
1185  *
1186  * Return: size of descriptor written in words or negative number on error
1187  */
1188 static inline int
1189 cnstr_shdsc_ipsec_new_decap(uint32_t *descbuf, bool ps,
1190                             bool swap,
1191                             struct ipsec_decap_pdb *pdb,
1192                             struct alginfo *cipherdata,
1193                             struct alginfo *authdata)
1194 {
1195         struct program prg;
1196         struct program *p = &prg;
1197
1198         LABEL(keyjmp);
1199         REFERENCE(pkeyjmp);
1200         LABEL(hdr);
1201         REFERENCE(phdr);
1202
1203         if (rta_sec_era < RTA_SEC_ERA_8) {
1204                 pr_err("IPsec new mode decap: available only for Era %d or above\n",
1205                        USER_SEC_ERA(RTA_SEC_ERA_8));
1206                 return -ENOTSUP;
1207         }
1208
1209         PROGRAM_CNTXT_INIT(p, descbuf, 0);
1210         if (swap)
1211                 PROGRAM_SET_BSWAP(p);
1212         if (ps)
1213                 PROGRAM_SET_36BIT_ADDR(p);
1214         phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
1215         __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
1216         SET_LABEL(p, hdr);
1217         pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1218         if (authdata->keylen)
1219                 __gen_auth_key(p, authdata);
1220         if (cipherdata->keylen)
1221                 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1222                     cipherdata->keylen, INLINE_KEY(cipherdata));
1223         SET_LABEL(p, keyjmp);
1224         PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
1225                  OP_PCLID_IPSEC_NEW,
1226                  (uint16_t)(cipherdata->algtype | authdata->algtype));
1227         PATCH_JUMP(p, pkeyjmp, keyjmp);
1228         PATCH_HDR(p, phdr, hdr);
1229         return PROGRAM_FINALIZE(p);
1230 }
1231
1232 /**
1233  * IPSEC_AUTH_VAR_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1234  *                              for the case of variable-length authentication
1235  *                              only data.
1236  *                              Note: Only for SoCs with SEC_ERA >= 3.
1237  *
1238  * Accounts only for the "base" commands and is intended to be used by upper
1239  * layers to determine whether keys can be inlined or not. To be used as first
1240  * parameter of rta_inline_query().
1241  */
1242 #define IPSEC_AUTH_VAR_BASE_DESC_LEN    (27 * CAAM_CMD_SZ)
1243
1244 /**
1245  * IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor
1246  *                              length for variable-length authentication only
1247  *                              data.
1248  *                              Note: Only for SoCs with SEC_ERA >= 3.
1249  *
1250  * Accounts only for the "base" commands and is intended to be used by upper
1251  * layers to determine whether key can be inlined or not. To be used as first
1252  * parameter of rta_inline_query().
1253  */
1254 #define IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN    \
1255                                 (IPSEC_AUTH_VAR_BASE_DESC_LEN + CAAM_CMD_SZ)
1256
1257 /**
1258  * IPSEC_AUTH_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1259  *
1260  * Accounts only for the "base" commands and is intended to be used by upper
1261  * layers to determine whether key can be inlined or not. To be used as first
1262  * parameter of rta_inline_query().
1263  */
1264 #define IPSEC_AUTH_BASE_DESC_LEN        (19 * CAAM_CMD_SZ)
1265
1266 /**
1267  * IPSEC_AUTH_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor length
1268  *
1269  * Accounts only for the "base" commands and is intended to be used by upper
1270  * layers to determine whether key can be inlined or not. To be used as first
1271  * parameter of rta_inline_query().
1272  */
1273 #define IPSEC_AUTH_AES_DEC_BASE_DESC_LEN        (IPSEC_AUTH_BASE_DESC_LEN + \
1274                                                 CAAM_CMD_SZ)
1275
1276 /**
1277  * cnstr_shdsc_authenc - authenc-like descriptor
1278  * @descbuf: pointer to buffer used for descriptor construction
1279  * @ps: if 36/40bit addressing is desired, this parameter must be true
1280  * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
1281  * @cipherdata: pointer to block cipher transform definitions.
1282  *              Valid algorithm values one of OP_ALG_ALGSEL_* {DES, 3DES, AES}
1283  *              Valid modes for:
1284  *                  AES: OP_ALG_AAI_* {CBC, CTR}
1285  *                  DES, 3DES: OP_ALG_AAI_CBC
1286  * @authdata: pointer to authentication transform definitions.
1287  *            Valid algorithm values - one of OP_ALG_ALGSEL_* {MD5, SHA1,
1288  *            SHA224, SHA256, SHA384, SHA512}
1289  * Note: The key for authentication is supposed to be given as plain text.
1290  * Note: There's no support for keys longer than the block size of the
1291  *       underlying hash function, according to the selected algorithm.
1292  *
1293  * @ivlen: length of the IV to be read from the input frame, before any data
1294  *         to be processed
1295  * @auth_only_len: length of the data to be authenticated-only (commonly IP
1296  *                 header, IV, Sequence number and SPI)
1297  * Note: Extended Sequence Number processing is NOT supported
1298  *
1299  * @trunc_len: the length of the ICV to be written to the output frame. If 0,
1300  *             then the corresponding length of the digest, according to the
1301  *             selected algorithm shall be used.
1302  * @dir: Protocol direction, encapsulation or decapsulation (DIR_ENC/DIR_DEC)
1303  *
1304  * Note: Here's how the input frame needs to be formatted so that the processing
1305  *       will be done correctly:
1306  * For encapsulation:
1307  *     Input:
1308  * +----+----------------+---------------------------------------------+
1309  * | IV | Auth-only data | Padded data to be authenticated & Encrypted |
1310  * +----+----------------+---------------------------------------------+
1311  *     Output:
1312  * +--------------------------------------+
1313  * | Authenticated & Encrypted data | ICV |
1314  * +--------------------------------+-----+
1315
1316  * For decapsulation:
1317  *     Input:
1318  * +----+----------------+--------------------------------+-----+
1319  * | IV | Auth-only data | Authenticated & Encrypted data | ICV |
1320  * +----+----------------+--------------------------------+-----+
1321  *     Output:
1322  * +----+--------------------------+
1323  * | Decrypted & authenticated data |
1324  * +----+--------------------------+
1325  *
1326  * Note: This descriptor can use per-packet commands, encoded as below in the
1327  *       DPOVRD register:
1328  * 32    24    16               0
1329  * +------+---------------------+
1330  * | 0x80 | 0x00| auth_only_len |
1331  * +------+---------------------+
1332  *
1333  * This mechanism is available only for SoCs having SEC ERA >= 3. In other
1334  * words, this will not work for P4080TO2
1335  *
1336  * Note: The descriptor does not add any kind of padding to the input data,
1337  *       so the upper layer needs to ensure that the data is padded properly,
1338  *       according to the selected cipher. Failure to do so will result in
1339  *       the descriptor failing with a data-size error.
1340  *
1341  * Return: size of descriptor written in words or negative number on error
1342  */
1343 static inline int
1344 cnstr_shdsc_authenc(uint32_t *descbuf, bool ps, bool swap,
1345                     struct alginfo *cipherdata,
1346                     struct alginfo *authdata,
1347                     uint16_t ivlen, uint16_t auth_only_len,
1348                     uint8_t trunc_len, uint8_t dir)
1349 {
1350         struct program prg;
1351         struct program *p = &prg;
1352         const bool need_dk = (dir == DIR_DEC) &&
1353                              (cipherdata->algtype == OP_ALG_ALGSEL_AES) &&
1354                              (cipherdata->algmode == OP_ALG_AAI_CBC);
1355
1356         LABEL(skip_patch_len);
1357         LABEL(keyjmp);
1358         LABEL(skipkeys);
1359         LABEL(aonly_len_offset);
1360         REFERENCE(pskip_patch_len);
1361         REFERENCE(pkeyjmp);
1362         REFERENCE(pskipkeys);
1363         REFERENCE(read_len);
1364         REFERENCE(write_len);
1365
1366         PROGRAM_CNTXT_INIT(p, descbuf, 0);
1367
1368         if (swap)
1369                 PROGRAM_SET_BSWAP(p);
1370         if (ps)
1371                 PROGRAM_SET_36BIT_ADDR(p);
1372
1373         /*
1374          * Since we currently assume that key length is equal to hash digest
1375          * size, it's ok to truncate keylen value.
1376          */
1377         trunc_len = trunc_len && (trunc_len < authdata->keylen) ?
1378                         trunc_len : (uint8_t)authdata->keylen;
1379
1380         SHR_HDR(p, SHR_SERIAL, 1, SC);
1381
1382         /*
1383          * M0 will contain the value provided by the user when creating
1384          * the shared descriptor. If the user provided an override in
1385          * DPOVRD, then M0 will contain that value
1386          */
1387         MATHB(p, MATH0, ADD, auth_only_len, MATH0, 4, IMMED2);
1388
1389         if (rta_sec_era >= RTA_SEC_ERA_3) {
1390                 /*
1391                  * Check if the user wants to override the auth-only len
1392                  */
1393                 MATHB(p, DPOVRD, ADD, 0x80000000, MATH2, 4, IMMED2);
1394
1395                 /*
1396                  * No need to patch the length of the auth-only data read if
1397                  * the user did not override it
1398                  */
1399                 pskip_patch_len = JUMP(p, skip_patch_len, LOCAL_JUMP, ALL_TRUE,
1400                                   MATH_N);
1401
1402                 /* Get auth-only len in M0 */
1403                 MATHB(p, MATH2, AND, 0xFFFF, MATH0, 4, IMMED2);
1404
1405                 /*
1406                  * Since M0 is used in calculations, don't mangle it, copy
1407                  * its content to M1 and use this for patching.
1408                  */
1409                 MATHB(p, MATH0, ADD, MATH1, MATH1, 4, 0);
1410
1411                 read_len = MOVE(p, DESCBUF, 0, MATH1, 0, 6, WAITCOMP | IMMED);
1412                 write_len = MOVE(p, MATH1, 0, DESCBUF, 0, 8, WAITCOMP | IMMED);
1413
1414                 SET_LABEL(p, skip_patch_len);
1415         }
1416         /*
1417          * MATH0 contains the value in DPOVRD w/o the MSB, or the initial
1418          * value, as provided by the user at descriptor creation time
1419          */
1420         if (dir == DIR_ENC)
1421                 MATHB(p, MATH0, ADD, ivlen, MATH0, 4, IMMED2);
1422         else
1423                 MATHB(p, MATH0, ADD, ivlen + trunc_len, MATH0, 4, IMMED2);
1424
1425         pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1426
1427         KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1428             INLINE_KEY(authdata));
1429
1430         /* Insert Key */
1431         KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1432             cipherdata->keylen, INLINE_KEY(cipherdata));
1433
1434         /* Do operation */
1435         ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC,
1436                       OP_ALG_AS_INITFINAL,
1437                       dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1438                       dir);
1439
1440         if (need_dk)
1441                 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode,
1442                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1443         pskipkeys = JUMP(p, skipkeys, LOCAL_JUMP, ALL_TRUE, 0);
1444
1445         SET_LABEL(p, keyjmp);
1446
1447         ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
1448                       OP_ALG_AS_INITFINAL,
1449                       dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1450                       dir);
1451
1452         if (need_dk) {
1453                 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode |
1454                               OP_ALG_AAI_DK, OP_ALG_AS_INITFINAL,
1455                               ICV_CHECK_DISABLE, dir);
1456                 SET_LABEL(p, skipkeys);
1457         } else {
1458                 SET_LABEL(p, skipkeys);
1459                 ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
1460                               OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1461         }
1462
1463         /*
1464          * Prepare the length of the data to be both encrypted/decrypted
1465          * and authenticated/checked
1466          */
1467         MATHB(p, SEQINSZ, SUB, MATH0, VSEQINSZ, 4, 0);
1468
1469         MATHB(p, VSEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
1470
1471         /* Prepare for writing the output frame */
1472         SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1473
1474         SET_LABEL(p, aonly_len_offset);
1475
1476         /* Read IV */
1477         if (cipherdata->algmode == OP_ALG_AAI_CTR)
1478                 SEQLOAD(p, CONTEXT1, 16, ivlen, 0);
1479         else
1480                 SEQLOAD(p, CONTEXT1, 0, ivlen, 0);
1481
1482         /*
1483          * Read data needed only for authentication. This is overwritten above
1484          * if the user requested it.
1485          */
1486         SEQFIFOLOAD(p, MSG2, auth_only_len, 0);
1487
1488         if (dir == DIR_ENC) {
1489                 /*
1490                  * Read input plaintext, encrypt and authenticate & write to
1491                  * output
1492                  */
1493                 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
1494
1495                 /* Finally, write the ICV */
1496                 SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
1497         } else {
1498                 /*
1499                  * Read input ciphertext, decrypt and authenticate & write to
1500                  * output
1501                  */
1502                 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
1503
1504                 /* Read the ICV to check */
1505                 SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
1506         }
1507
1508         PATCH_JUMP(p, pkeyjmp, keyjmp);
1509         PATCH_JUMP(p, pskipkeys, skipkeys);
1510         PATCH_JUMP(p, pskipkeys, skipkeys);
1511
1512         if (rta_sec_era >= RTA_SEC_ERA_3) {
1513                 PATCH_JUMP(p, pskip_patch_len, skip_patch_len);
1514                 PATCH_MOVE(p, read_len, aonly_len_offset);
1515                 PATCH_MOVE(p, write_len, aonly_len_offset);
1516         }
1517
1518         return PROGRAM_FINALIZE(p);
1519 }
1520
1521 #endif /* __DESC_IPSEC_H__ */