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