1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
4 * Copyright 2016,2019 NXP
8 #ifndef __DESC_IPSEC_H__
9 #define __DESC_IPSEC_H__
15 * DOC: IPsec Shared Descriptor Constructors
17 * Shared descriptors for IPsec protocol.
20 /* General IPSec ESP encap / decap PDB options */
23 * PDBOPTS_ESP_ESN - Extended sequence included
25 #define PDBOPTS_ESP_ESN 0x10
28 * PDBOPTS_ESP_IPVSN - Process IPv6 header
30 * Valid only for IPsec legacy mode.
32 #define PDBOPTS_ESP_IPVSN 0x02
35 * PDBOPTS_ESP_TUNNEL - Tunnel mode next-header byte
37 * Valid only for IPsec legacy mode.
39 #define PDBOPTS_ESP_TUNNEL 0x01
41 /* IPSec ESP Encap PDB options */
44 * PDBOPTS_ESP_UPDATE_CSUM - Update ip header checksum
46 * Valid only for IPsec legacy mode.
48 #define PDBOPTS_ESP_UPDATE_CSUM 0x80
51 * PDBOPTS_ESP_DIFFSERV - Copy TOS/TC from inner iphdr
53 * Valid only for IPsec legacy mode.
55 #define PDBOPTS_ESP_DIFFSERV 0x40
58 * PDBOPTS_ESP_IVSRC - IV comes from internal random gen
60 #define PDBOPTS_ESP_IVSRC 0x20
63 * PDBOPTS_ESP_IPHDRSRC - IP header comes from PDB
65 * Valid only for IPsec legacy mode.
67 #define PDBOPTS_ESP_IPHDRSRC 0x08
70 * PDBOPTS_ESP_INCIPHDR - Prepend IP header to output frame
72 * Valid only for IPsec legacy mode.
74 #define PDBOPTS_ESP_INCIPHDR 0x04
77 * PDBOPTS_ESP_OIHI_MASK - Mask for Outer IP Header Included
79 * Valid only for IPsec new mode.
81 #define PDBOPTS_ESP_OIHI_MASK 0x0c
84 * PDBOPTS_ESP_OIHI_PDB_INL - Prepend IP header to output frame from PDB (where
87 * Valid only for IPsec new mode.
89 #define PDBOPTS_ESP_OIHI_PDB_INL 0x0c
92 * PDBOPTS_ESP_OIHI_PDB_REF - Prepend IP header to output frame from PDB
93 * (referenced by pointer).
95 * Vlid only for IPsec new mode.
97 #define PDBOPTS_ESP_OIHI_PDB_REF 0x08
100 * PDBOPTS_ESP_OIHI_IF - Prepend IP header to output frame from input frame
102 * Valid only for IPsec new mode.
104 #define PDBOPTS_ESP_OIHI_IF 0x04
107 * PDBOPTS_ESP_NAT - Enable RFC 3948 UDP-encapsulated-ESP
109 * Valid only for IPsec new mode.
111 #define PDBOPTS_ESP_NAT 0x02
114 * PDBOPTS_ESP_NUC - Enable NAT UDP Checksum
116 * Valid only for IPsec new mode.
118 #define PDBOPTS_ESP_NUC 0x01
120 /* IPSec ESP Decap PDB options */
123 * PDBOPTS_ESP_ARS_MASK - antireplay window mask
125 #define PDBOPTS_ESP_ARS_MASK 0xc0
128 * PDBOPTS_ESP_ARSNONE - No antireplay window
130 #define PDBOPTS_ESP_ARSNONE 0x00
133 * PDBOPTS_ESP_ARS64 - 64-entry antireplay window
135 #define PDBOPTS_ESP_ARS64 0xc0
138 * PDBOPTS_ESP_ARS128 - 128-entry antireplay window
140 * Valid only for IPsec new mode.
142 #define PDBOPTS_ESP_ARS128 0x80
145 * PDBOPTS_ESP_ARS32 - 32-entry antireplay window
147 #define PDBOPTS_ESP_ARS32 0x40
150 * PDBOPTS_ESP_VERIFY_CSUM - Validate ip header checksum
152 * Valid only for IPsec legacy mode.
154 #define PDBOPTS_ESP_VERIFY_CSUM 0x20
157 * PDBOPTS_ESP_TECN - Implement RRFC6040 ECN tunneling from outer header to
160 * Valid only for IPsec new mode.
162 #define PDBOPTS_ESP_TECN 0x20
165 * PDBOPTS_ESP_OUTFMT - Output only decapsulation
167 * Valid only for IPsec legacy mode.
169 #define PDBOPTS_ESP_OUTFMT 0x08
172 * PDBOPTS_ESP_AOFL - Adjust out frame len
174 * Valid only for IPsec legacy mode and for SEC >= 5.3.
176 #define PDBOPTS_ESP_AOFL 0x04
179 * PDBOPTS_ESP_ETU - EtherType Update
181 * Add corresponding ethertype (0x0800 for IPv4, 0x86dd for IPv6) in the output
183 * Valid only for IPsec new mode.
185 #define PDBOPTS_ESP_ETU 0x01
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)
197 * PDBHMO_ESP_DECAP_DTTL - IPsec ESP decrement TTL (IPv4) / Hop limit (IPv6)
200 #define PDBHMO_ESP_DECAP_DTTL (0x02 << PDBHMO_ESP_DECAP_SHIFT)
203 * PDBHMO_ESP_ENCAP_DTTL - IPsec ESP increment TTL (IPv4) / Hop limit (IPv6)
206 #define PDBHMO_ESP_ENCAP_DTTL (0x02 << PDBHMO_ESP_ENCAP_SHIFT)
209 * PDBHMO_ESP_DIFFSERV - (Decap) DiffServ Copy - Copy the IPv4 TOS or IPv6
210 * Traffic Class byte from the outer IP header to the
213 #define PDBHMO_ESP_DIFFSERV (0x01 << PDBHMO_ESP_DECAP_SHIFT)
216 * PDBHMO_ESP_SNR - (Encap) - Sequence Number Rollover control
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.
222 #define PDBHMO_ESP_SNR (0x01 << PDBHMO_ESP_ENCAP_SHIFT)
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.
229 #define PDBHMO_ESP_DFBIT (0x04 << PDBHMO_ESP_ENCAP_SHIFT)
232 * PDBHMO_ESP_DFV - (Decap) - DF bit value
234 * If ODF = 1, DF bit in output frame is replaced by DFV.
235 * Valid only from SEC Era 5 onwards.
237 #define PDBHMO_ESP_DFV (0x04 << PDBHMO_ESP_DECAP_SHIFT)
240 * PDBHMO_ESP_ODF - (Decap) Override DF bit in IPv4 header of decapsulated
243 * If ODF = 1, DF is replaced with the value of DFV bit.
244 * Valid only from SEC Era 5 onwards.
246 #define PDBHMO_ESP_ODF (0x08 << PDBHMO_ESP_DECAP_SHIFT)
249 * struct ipsec_encap_cbc - PDB part for IPsec CBC encapsulation
250 * @iv: 16-byte array initialization vector
252 struct ipsec_encap_cbc {
258 * struct ipsec_encap_ctr - PDB part for IPsec CTR encapsulation
259 * @ctr_nonce: 4-byte nonce
260 * @ctr_initial: initial count constant
261 * @iv: initialization vector
263 struct ipsec_encap_ctr {
265 uint32_t ctr_initial;
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
279 struct ipsec_encap_ccm {
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
291 struct ipsec_encap_gcm {
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
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)
310 * Opt. IP Hdr Len - 16b
311 * @ip_hdr: optional IP Header content (only for IPsec legacy mode)
313 struct ipsec_encap_pdb {
315 uint32_t seq_num_ext_hi;
318 struct ipsec_encap_cbc cbc;
319 struct ipsec_encap_ctr ctr;
320 struct ipsec_encap_ccm ccm;
321 struct ipsec_encap_gcm gcm;
328 static inline unsigned int
329 __rta_copy_ipsec_encap_pdb(struct program *program,
330 struct ipsec_encap_pdb *pdb,
333 unsigned int start_pc = program->current_pc;
335 __rta_out32(program, pdb->options);
336 __rta_out32(program, pdb->seq_num_ext_hi);
337 __rta_out32(program, pdb->seq_num);
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));
348 case OP_PCL_IPSEC_AES_CTR:
349 rta_copy_data(program, (uint8_t *)&pdb->ctr.ctr_nonce, 4);
350 __rta_out32(program, pdb->ctr.ctr_initial);
351 rta_copy_data(program, pdb->ctr.iv, sizeof(pdb->ctr.iv));
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);
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);
372 __rta_out32(program, pdb->spi);
373 __rta_out32(program, pdb->ip_hdr_len);
379 * struct ipsec_decap_cbc - PDB part for IPsec CBC decapsulation
380 * @rsvd: reserved, do not use
382 struct ipsec_decap_cbc {
387 * struct ipsec_decap_ctr - PDB part for IPsec CTR decapsulation
388 * @ctr_nonce: 4-byte nonce
389 * @ctr_initial: initial count constant
391 struct ipsec_decap_ctr {
393 uint32_t ctr_initial;
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
405 struct ipsec_decap_ccm {
411 * struct ipsec_decap_gcm - PDB part for IPsec GCN decapsulation
413 * @rsvd: reserved, do not use
415 struct ipsec_decap_gcm {
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
432 struct ipsec_decap_pdb {
435 struct ipsec_decap_cbc cbc;
436 struct ipsec_decap_ctr ctr;
437 struct ipsec_decap_ccm ccm;
438 struct ipsec_decap_gcm gcm;
440 uint32_t seq_num_ext_hi;
442 uint32_t anti_replay[4];
445 static inline unsigned int
446 __rta_copy_ipsec_decap_pdb(struct program *program,
447 struct ipsec_decap_pdb *pdb,
450 unsigned int start_pc = program->current_pc;
453 __rta_out32(program, pdb->options);
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]);
465 case OP_PCL_IPSEC_AES_CTR:
466 rta_copy_data(program, (uint8_t *)&pdb->ctr.ctr_nonce, 4);
467 __rta_out32(program, pdb->ctr.ctr_initial);
470 case OP_PCL_IPSEC_AES_CCM8:
471 case OP_PCL_IPSEC_AES_CCM12:
472 case OP_PCL_IPSEC_AES_CCM16:
473 rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
474 __rta_out32(program, pdb->ccm.ccm_opt);
477 case OP_PCL_IPSEC_AES_GCM8:
478 case OP_PCL_IPSEC_AES_GCM12:
479 case OP_PCL_IPSEC_AES_GCM16:
480 case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
481 rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
482 __rta_out32(program, pdb->gcm.rsvd);
486 __rta_out32(program, pdb->seq_num_ext_hi);
487 __rta_out32(program, pdb->seq_num);
489 switch (pdb->options & PDBOPTS_ESP_ARS_MASK) {
490 case PDBOPTS_ESP_ARS128:
493 case PDBOPTS_ESP_ARS64:
496 case PDBOPTS_ESP_ARS32:
499 case PDBOPTS_ESP_ARSNONE:
505 for (i = 0; i < ars; i++)
506 __rta_out_be32(program, pdb->anti_replay[i]);
512 * enum ipsec_icv_size - Type selectors for icv size in IPsec protocol
513 * @IPSEC_ICV_MD5_SIZE: full-length MD5 ICV
514 * @IPSEC_ICV_MD5_TRUNC_SIZE: truncated MD5 ICV
516 enum ipsec_icv_size {
517 IPSEC_ICV_MD5_SIZE = 16,
518 IPSEC_ICV_MD5_TRUNC_SIZE = 12
522 * IPSec ESP Datapath Protocol Override Register (DPOVRD)
523 * IPSEC_N_* defines are for IPsec new mode.
527 * IPSEC_DPOVRD_USE - DPOVRD will override values specified in the PDB
529 #define IPSEC_DPOVRD_USE BIT(31)
532 * IPSEC_DPOVRD_ECN_SHIFT - Explicit Congestion Notification
534 * If set, MSB of the 4 bits indicates that the 2 LSBs will replace the ECN bits
537 #define IPSEC_DPOVRD_ECN_SHIFT 24
540 * IPSEC_DPOVRD_ECN_MASK - See IPSEC_DPOVRD_ECN_SHIFT
542 #define IPSEC_DPOVRD_ECN_MASK (0xf << IPSEC_ENCAP_DPOVRD_ECN_SHIFT)
545 * IPSEC_DPOVRD_IP_HDR_LEN_SHIFT - The length (in bytes) of the portion of the
546 * IP header that is not encrypted
548 #define IPSEC_DPOVRD_IP_HDR_LEN_SHIFT 16
551 * IPSEC_DPOVRD_IP_HDR_LEN_MASK - See IPSEC_DPOVRD_IP_HDR_LEN_SHIFT
553 #define IPSEC_DPOVRD_IP_HDR_LEN_MASK (0xff << IPSEC_DPOVRD_IP_HDR_LEN_SHIFT)
556 * IPSEC_DPOVRD_NH_OFFSET_SHIFT - The location of the next header field within
557 * the IP header of the transport mode packet
560 * ESP_Trailer_NH <-- IP_Hdr[DPOVRD[NH_OFFSET]]
561 * IP_Hdr[DPOVRD[NH_OFFSET]] <-- DPOVRD[NH]
563 * IP_Hdr[DPOVRD[NH_OFFSET]] <-- ESP_Trailer_NH
565 #define IPSEC_DPOVRD_NH_OFFSET_SHIFT 8
568 * IPSEC_DPOVRD_NH_OFFSET_MASK - See IPSEC_DPOVRD_NH_OFFSET_SHIFT
570 #define IPSEC_DPOVRD_NH_OFFSET_MASK (0xff << IPSEC_DPOVRD_NH_OFFSET_SHIFT)
573 * IPSEC_DPOVRD_NH_MASK - See IPSEC_DPOVRD_NH_OFFSET_SHIFT
574 * Valid only for encapsulation.
576 #define IPSEC_DPOVRD_NH_MASK 0xff
579 * IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT - Outer IP header Material length (encap)
580 * Valid only if L2_COPY is not set.
582 #define IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT 16
585 * IPSEC_N_ENCAP_DPOVRD_OIM_LEN_MASK - See IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT
587 #define IPSEC_N_ENCAP_DPOVRD_OIM_LEN_MASK \
588 (0xfff << IPSEC_N_ENCAP_DPOVRD_OIM_LEN_SHIFT)
591 * IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT - L2 header length
592 * Valid only if L2_COPY is set.
594 #define IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT 16
597 * IPSEC_N_ENCAP_DPOVRD_L2_LEN_MASK - See IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT
599 #define IPSEC_N_ENCAP_DPOVRD_L2_LEN_MASK \
600 (0xff << IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT)
603 * IPSEC_N_ENCAP_DPOVRD_OIMIF - Outer IP header Material in Input Frame
605 #define IPSEC_N_ENCAP_DPOVRD_OIMIF BIT(15)
608 * IPSEC_N_ENCAP_DPOVRD_L2_COPY - L2 header present in input frame
610 * Note: For Era <= 8, this bit is reserved (not used) by HW.
612 #define IPSEC_N_ENCAP_DPOVRD_L2_COPY BIT(14)
615 * IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT - Actual Outer IP Header Offset (encap)
617 #define IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT 8
620 * IPSEC_N_ENCAP_DPOVRD_AOIPHO_MASK - See IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT
622 #define IPSEC_N_ENCAP_DPOVRD_AOIPHO_MASK \
623 (0x3c << IPSEC_N_ENCAP_DPOVRD_AOIPHO_SHIFT)
626 * IPSEC_N_ENCAP_DPOVRD_NH_MASK - Next Header
628 * Used in the Next Header field of the encapsulated payload.
630 #define IPSEC_N_ENCAP_DPOVRD_NH_MASK 0xff
633 * IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT - Actual Outer IP Header Offset (decap)
635 #define IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT 12
638 * IPSEC_N_DECAP_DPOVRD_AOIPHO_MASK - See IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT
640 #define IPSEC_N_DECAP_DPOVRD_AOIPHO_MASK \
641 (0xff << IPSEC_N_DECAP_DPOVRD_AOIPHO_SHIFT)
644 * IPSEC_N_DECAP_DPOVRD_OIM_LEN_MASK - Outer IP header Material length (decap)
646 #define IPSEC_N_DECAP_DPOVRD_OIM_LEN_MASK 0xfff
648 static inline void __gen_auth_key(struct program *program,
649 struct alginfo *authdata)
653 switch (authdata->algtype & OP_PCL_IPSEC_AUTH_MASK) {
654 case OP_PCL_IPSEC_HMAC_MD5_96:
655 case OP_PCL_IPSEC_HMAC_MD5_128:
656 dkp_protid = OP_PCLID_DKP_MD5;
658 case OP_PCL_IPSEC_HMAC_SHA1_96:
659 case OP_PCL_IPSEC_HMAC_SHA1_160:
660 dkp_protid = OP_PCLID_DKP_SHA1;
662 case OP_PCL_IPSEC_HMAC_SHA2_256_128:
663 dkp_protid = OP_PCLID_DKP_SHA256;
665 case OP_PCL_IPSEC_HMAC_SHA2_384_192:
666 dkp_protid = OP_PCLID_DKP_SHA384;
668 case OP_PCL_IPSEC_HMAC_SHA2_512_256:
669 dkp_protid = OP_PCLID_DKP_SHA512;
672 KEY(program, KEY2, authdata->key_enc_flags, authdata->key,
673 authdata->keylen, INLINE_KEY(authdata));
677 if (authdata->key_type == RTA_DATA_PTR)
678 DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_PTR,
679 OP_PCL_DKP_DST_PTR, (uint16_t)authdata->keylen,
680 authdata->key, authdata->key_type);
682 DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_IMM,
683 OP_PCL_DKP_DST_IMM, (uint16_t)authdata->keylen,
684 authdata->key, authdata->key_type);
688 * cnstr_shdsc_ipsec_encap - IPSec ESP encapsulation protocol-level shared
690 * @descbuf: pointer to buffer used for descriptor construction
691 * @ps: if 36/40bit addressing is desired, this parameter must be true
692 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
693 * @share: sharing type of shared descriptor
694 * @pdb: pointer to the PDB to be used with this descriptor
695 * This structure will be copied inline to the descriptor under
696 * construction. No error checking will be made. Refer to the
697 * block guide for a details of the encapsulation PDB.
698 * @cipherdata: pointer to block cipher transform definitions
699 * Valid algorithm values - one of OP_PCL_IPSEC_*
700 * @authdata: pointer to authentication transform definitions
701 * If an authentication key is required by the protocol:
702 * -For SEC Eras 1-5, an MDHA split key must be provided;
703 * Note that the size of the split key itself must be specified.
704 * -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
705 * Key Protocol) will be used to compute MDHA on the fly in HW.
706 * Valid algorithm values - one of OP_PCL_IPSEC_*
708 * Return: size of descriptor written in words or negative number on error
711 cnstr_shdsc_ipsec_encap(uint32_t *descbuf, bool ps, bool swap,
712 enum rta_share_type share,
713 struct ipsec_encap_pdb *pdb,
714 struct alginfo *cipherdata,
715 struct alginfo *authdata)
718 struct program *p = &prg;
725 PROGRAM_CNTXT_INIT(p, descbuf, 0);
727 PROGRAM_SET_BSWAP(p);
729 PROGRAM_SET_36BIT_ADDR(p);
730 phdr = SHR_HDR(p, share, hdr, 0);
731 __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
732 COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
734 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
735 if (authdata->keylen) {
736 if (rta_sec_era < RTA_SEC_ERA_6)
737 KEY(p, MDHA_SPLIT_KEY, authdata->key_enc_flags,
738 authdata->key, authdata->keylen,
739 INLINE_KEY(authdata));
741 __gen_auth_key(p, authdata);
743 if (cipherdata->keylen)
744 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
745 cipherdata->keylen, INLINE_KEY(cipherdata));
746 SET_LABEL(p, keyjmp);
747 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
749 (uint16_t)(cipherdata->algtype | authdata->algtype));
750 PATCH_JUMP(p, pkeyjmp, keyjmp);
751 PATCH_HDR(p, phdr, hdr);
752 return PROGRAM_FINALIZE(p);
756 * cnstr_shdsc_ipsec_decap - IPSec ESP decapsulation protocol-level shared
758 * @descbuf: pointer to buffer used for descriptor construction
759 * @ps: if 36/40bit addressing is desired, this parameter must be true
760 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
761 * @share: sharing type of shared descriptor
762 * @pdb: pointer to the PDB to be used with this descriptor
763 * This structure will be copied inline to the descriptor under
764 * construction. No error checking will be made. Refer to the
765 * block guide for details about the decapsulation PDB.
766 * @cipherdata: pointer to block cipher transform definitions.
767 * Valid algorithm values - one of OP_PCL_IPSEC_*
768 * @authdata: pointer to authentication transform definitions
769 * If an authentication key is required by the protocol:
770 * -For SEC Eras 1-5, an MDHA split key must be provided;
771 * Note that the size of the split key itself must be specified.
772 * -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
773 * Key Protocol) will be used to compute MDHA on the fly in HW.
774 * Valid algorithm values - one of OP_PCL_IPSEC_*
776 * Return: size of descriptor written in words or negative number on error
779 cnstr_shdsc_ipsec_decap(uint32_t *descbuf, bool ps, bool swap,
780 enum rta_share_type share,
781 struct ipsec_decap_pdb *pdb,
782 struct alginfo *cipherdata,
783 struct alginfo *authdata)
786 struct program *p = &prg;
793 PROGRAM_CNTXT_INIT(p, descbuf, 0);
795 PROGRAM_SET_BSWAP(p);
797 PROGRAM_SET_36BIT_ADDR(p);
798 phdr = SHR_HDR(p, share, hdr, 0);
799 __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
801 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
802 if (authdata->keylen) {
803 if (rta_sec_era < RTA_SEC_ERA_6)
804 KEY(p, MDHA_SPLIT_KEY, authdata->key_enc_flags,
805 authdata->key, authdata->keylen,
806 INLINE_KEY(authdata));
808 __gen_auth_key(p, authdata);
810 if (cipherdata->keylen)
811 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
812 cipherdata->keylen, INLINE_KEY(cipherdata));
813 SET_LABEL(p, keyjmp);
814 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
816 (uint16_t)(cipherdata->algtype | authdata->algtype));
817 PATCH_JUMP(p, pkeyjmp, keyjmp);
818 PATCH_HDR(p, phdr, hdr);
819 return PROGRAM_FINALIZE(p);
823 * cnstr_shdsc_ipsec_encap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
824 * AES-XCBC-MAC-96 ESP encapsulation shared descriptor.
825 * @descbuf: pointer to buffer used for descriptor construction
826 * @pdb: pointer to the PDB to be used with this descriptor
827 * This structure will be copied inline to the descriptor under
828 * construction. No error checking will be made. Refer to the
829 * block guide for a details of the encapsulation PDB.
830 * @cipherdata: pointer to block cipher transform definitions
831 * Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
832 * @authdata: pointer to authentication transform definitions
833 * Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
835 * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
836 * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
837 * Outer/Transport IP Header is present in the encapsulation output packet.
838 * The descriptor performs DES-CBC/3DES-CBC & HMAC-MD5-96 and then rereads
839 * the input packet to do the AES-XCBC-MAC-96 calculation and to overwrite
841 * The descriptor uses all the benefits of the built-in protocol by computing
842 * the IPsec ESP with a hardware supported algorithms combination
843 * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
844 * was chosen in order to speed up the computational time for this intermediate
846 * Warning: The user must allocate at least 32 bytes for the authentication key
847 * (in order to use it also with HMAC-MD5-96),even when using a shorter key
848 * for the AES-XCBC-MAC-96.
850 * Return: size of descriptor written in words or negative number on error
853 cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
854 struct ipsec_encap_pdb *pdb,
855 struct alginfo *cipherdata,
856 struct alginfo *authdata)
859 struct program *p = &prg;
865 LABEL(swapped_seqin_fields);
866 LABEL(swapped_seqin_ptr);
869 REFERENCE(move_outlen);
870 REFERENCE(move_seqout_ptr);
871 REFERENCE(swapped_seqin_ptr_jump);
872 REFERENCE(write_swapped_seqin_ptr);
874 PROGRAM_CNTXT_INIT(p, descbuf, 0);
875 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
876 __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
877 COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
879 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
881 * Hard-coded KEY arguments. The descriptor uses all the benefits of
882 * the built-in protocol by computing the IPsec ESP with a hardware
883 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
884 * The HMAC-MD5 authentication algorithm was chosen with
885 * the keys options from below in order to speed up the computational
886 * time for this intermediate step.
887 * Warning: The user must allocate at least 32 bytes for
888 * the authentication key (in order to use it also with HMAC-MD5-96),
889 * even when using a shorter key for the AES-XCBC-MAC-96.
891 KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
892 SET_LABEL(p, keyjump);
893 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
894 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
896 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
897 cipherdata->keylen, INLINE_KEY(cipherdata));
898 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL, OP_PCLID_IPSEC,
899 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
900 /* Swap SEQINPTR to SEQOUTPTR. */
901 move_seqout_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
902 MATHB(p, MATH1, AND, ~(CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR), MATH1,
905 * TODO: RTA currently doesn't support creating a LOAD command
906 * with another command as IMM.
907 * To be changed when proper support is added in RTA.
909 LOAD(p, 0xa00000e5, MATH3, 4, 4, IMMED);
910 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
911 write_swapped_seqin_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
913 swapped_seqin_ptr_jump = JUMP(p, swapped_seqin_ptr, LOCAL_JUMP,
915 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
916 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
918 SEQOUTPTR(p, 0, 65535, RTO);
919 move_outlen = MOVE(p, DESCBUF, 0, MATH0, 4, 8, WAITCOMP | IMMED);
921 (uint64_t)(pdb->ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE),
922 VSEQINSZ, 4, IMMED2);
923 MATHB(p, MATH0, SUB, IPSEC_ICV_MD5_TRUNC_SIZE, VSEQOUTSZ, 4, IMMED2);
924 KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
926 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
927 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
928 SEQFIFOLOAD(p, SKIP, pdb->ip_hdr_len, 0);
929 SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1 | LAST1);
930 SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
931 SEQSTORE(p, CONTEXT1, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
933 * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
934 * To be changed when proper support is added in RTA.
936 /* Label the Shared Descriptor Pointer */
937 SET_LABEL(p, shd_ptr);
939 /* Label the Output Pointer */
940 SET_LABEL(p, outptr);
942 /* Label the first word after JD */
943 SET_LABEL(p, swapped_seqin_fields);
944 swapped_seqin_fields += 8;
945 /* Label the second word after JD */
946 SET_LABEL(p, swapped_seqin_ptr);
947 swapped_seqin_ptr += 9;
949 PATCH_HDR(p, phdr, hdr);
950 PATCH_JUMP(p, pkeyjump, keyjump);
951 PATCH_JUMP(p, swapped_seqin_ptr_jump, swapped_seqin_ptr);
952 PATCH_MOVE(p, move_outlen, outptr);
953 PATCH_MOVE(p, move_seqout_ptr, shd_ptr);
954 PATCH_MOVE(p, write_swapped_seqin_ptr, swapped_seqin_fields);
955 return PROGRAM_FINALIZE(p);
959 * cnstr_shdsc_ipsec_decap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
960 * AES-XCBC-MAC-96 ESP decapsulation shared descriptor.
961 * @descbuf: pointer to buffer used for descriptor construction
962 * @pdb: pointer to the PDB to be used with this descriptor
963 * This structure will be copied inline to the descriptor under
964 * construction. No error checking will be made. Refer to the
965 * block guide for a details of the encapsulation PDB.
966 * @cipherdata: pointer to block cipher transform definitions
967 * Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
968 * @authdata: pointer to authentication transform definitions
969 * Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
971 * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
972 * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
973 * Outer/Transport IP Header is present in the decapsulation input packet.
974 * The descriptor computes the AES-XCBC-MAC-96 to check if the received ICV
975 * is correct, rereads the input packet to compute the MD5 ICV, overwrites
976 * the XCBC ICV, and then sends the modified input packet to the
977 * DES-CBC/3DES-CBC & HMAC-MD5-96 IPsec.
978 * The descriptor uses all the benefits of the built-in protocol by computing
979 * the IPsec ESP with a hardware supported algorithms combination
980 * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
981 * was chosen in order to speed up the computational time for this intermediate
983 * Warning: The user must allocate at least 32 bytes for the authentication key
984 * (in order to use it also with HMAC-MD5-96),even when using a shorter key
985 * for the AES-XCBC-MAC-96.
987 * Return: size of descriptor written in words or negative number on error
990 cnstr_shdsc_ipsec_decap_des_aes_xcbc(uint32_t *descbuf,
991 struct ipsec_decap_pdb *pdb,
992 struct alginfo *cipherdata,
993 struct alginfo *authdata)
996 struct program *p = &prg;
997 uint32_t ip_hdr_len = (pdb->options & PDBHDRLEN_MASK) >>
998 PDBHDRLEN_ESP_DECAP_SHIFT;
1006 LABEL(swapped_seqout_fields);
1007 LABEL(swapped_seqout_ptr);
1008 REFERENCE(seqout_ptr_jump);
1010 REFERENCE(pkeyjump);
1011 REFERENCE(move_jump);
1012 REFERENCE(move_jump_back);
1013 REFERENCE(move_seqin_ptr);
1014 REFERENCE(swapped_seqout_ptr_jump);
1015 REFERENCE(write_swapped_seqout_ptr);
1017 PROGRAM_CNTXT_INIT(p, descbuf, 0);
1018 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
1019 __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
1021 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
1023 * Hard-coded KEY arguments. The descriptor uses all the benefits of
1024 * the built-in protocol by computing the IPsec ESP with a hardware
1025 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
1026 * The HMAC-MD5 authentication algorithm was chosen with
1027 * the keys options from bellow in order to speed up the computational
1028 * time for this intermediate step.
1029 * Warning: The user must allocate at least 32 bytes for
1030 * the authentication key (in order to use it also with HMAC-MD5-96),
1031 * even when using a shorter key for the AES-XCBC-MAC-96.
1033 KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
1034 SET_LABEL(p, keyjump);
1035 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
1036 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
1038 KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
1039 INLINE_KEY(authdata));
1040 MATHB(p, SEQINSZ, SUB,
1041 (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), MATH0, 4,
1043 MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
1044 ALG_OPERATION(p, OP_ALG_ALGSEL_MD5, OP_ALG_AAI_HMAC_PRECOMP,
1045 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
1046 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
1047 OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
1048 SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
1049 SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1);
1050 SEQFIFOLOAD(p, ICV1, IPSEC_ICV_MD5_TRUNC_SIZE, FLUSH1 | LAST1);
1051 /* Swap SEQOUTPTR to SEQINPTR. */
1052 move_seqin_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
1053 MATHB(p, MATH1, OR, CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR, MATH1, 8,
1056 * TODO: RTA currently doesn't support creating a LOAD command
1057 * with another command as IMM.
1058 * To be changed when proper support is added in RTA.
1060 LOAD(p, 0xA00000e1, MATH3, 4, 4, IMMED);
1061 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
1062 write_swapped_seqout_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
1064 swapped_seqout_ptr_jump = JUMP(p, swapped_seqout_ptr, LOCAL_JUMP,
1067 * TODO: To be changed when proper support is added in RTA (can't load
1068 * a command that is also written by RTA).
1069 * Change when proper RTA support is added.
1071 SET_LABEL(p, jump_cmd);
1072 WORD(p, 0xA00000f3);
1073 SEQINPTR(p, 0, 65535, RTO);
1074 MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
1075 MATHB(p, MATH0, ADD, ip_hdr_len, VSEQOUTSZ, 4, IMMED2);
1076 move_jump = MOVE(p, DESCBUF, 0, OFIFO, 0, 8, WAITCOMP | IMMED);
1077 move_jump_back = MOVE(p, OFIFO, 0, DESCBUF, 0, 8, IMMED);
1078 SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
1079 SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
1080 SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
1081 SEQSTORE(p, CONTEXT2, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
1082 seqout_ptr_jump = JUMP(p, seqout_ptr, LOCAL_JUMP, ALL_TRUE, CALM);
1084 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
1085 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_CLR_C2MODE |
1086 CLRW_CLR_C2DATAS | CLRW_CLR_C2CTX | CLRW_RESET_CLS1_CHA, CLRW, 0,
1088 SEQINPTR(p, 0, 65535, RTO);
1089 MATHB(p, MATH0, ADD,
1090 (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), SEQINSZ, 4,
1092 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1093 cipherdata->keylen, INLINE_KEY(cipherdata));
1094 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL, OP_PCLID_IPSEC,
1095 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
1097 * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
1098 * To be changed when proper support is added in RTA.
1100 /* Label the SEQ OUT PTR */
1101 SET_LABEL(p, seqout_ptr);
1103 /* Label the Output Length */
1104 SET_LABEL(p, outlen);
1106 /* Label the SEQ IN PTR */
1107 SET_LABEL(p, seqin_ptr);
1109 /* Label the first word after JD */
1110 SET_LABEL(p, swapped_seqout_fields);
1111 swapped_seqout_fields += 8;
1112 /* Label the second word after JD */
1113 SET_LABEL(p, swapped_seqout_ptr);
1114 swapped_seqout_ptr += 9;
1116 PATCH_HDR(p, phdr, hdr);
1117 PATCH_JUMP(p, pkeyjump, keyjump);
1118 PATCH_JUMP(p, seqout_ptr_jump, seqout_ptr);
1119 PATCH_JUMP(p, swapped_seqout_ptr_jump, swapped_seqout_ptr);
1120 PATCH_MOVE(p, move_jump, jump_cmd);
1121 PATCH_MOVE(p, move_jump_back, seqin_ptr);
1122 PATCH_MOVE(p, move_seqin_ptr, outlen);
1123 PATCH_MOVE(p, write_swapped_seqout_ptr, swapped_seqout_fields);
1124 return PROGRAM_FINALIZE(p);
1128 * IPSEC_NEW_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor length
1130 * Accounts only for the "base" commands and is intended to be used by upper
1131 * layers to determine whether Outer IP Header and/or keys can be inlined or
1132 * not. To be used as first parameter of rta_inline_query().
1134 #define IPSEC_NEW_ENC_BASE_DESC_LEN (12 * CAAM_CMD_SZ + \
1135 sizeof(struct ipsec_encap_pdb))
1138 * IPSEC_NEW_NULL_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor
1139 * length for the case of
1140 * NULL encryption / authentication
1142 * Accounts only for the "base" commands and is intended to be used by upper
1143 * layers to determine whether Outer IP Header and/or key can be inlined or
1144 * not. To be used as first parameter of rta_inline_query().
1146 #define IPSEC_NEW_NULL_ENC_BASE_DESC_LEN (11 * CAAM_CMD_SZ + \
1147 sizeof(struct ipsec_encap_pdb))
1150 * cnstr_shdsc_ipsec_new_encap - IPSec new mode ESP encapsulation
1151 * protocol-level shared descriptor.
1152 * @descbuf: pointer to buffer used for descriptor construction
1153 * @ps: if 36/40bit addressing is desired, this parameter must be true
1154 * @swap: must be true when core endianness doesn't match SEC endianness
1155 * @share: sharing type of shared descriptor
1156 * @pdb: pointer to the PDB to be used with this descriptor
1157 * This structure will be copied inline to the descriptor under
1158 * construction. No error checking will be made. Refer to the
1159 * block guide for details about the encapsulation PDB.
1160 * @opt_ip_hdr: pointer to Optional IP Header
1161 * -if OIHI = PDBOPTS_ESP_OIHI_PDB_INL, opt_ip_hdr points to the buffer to
1162 * be inlined in the PDB. Number of bytes (buffer size) copied is provided
1163 * in pdb->ip_hdr_len.
1164 * -if OIHI = PDBOPTS_ESP_OIHI_PDB_REF, opt_ip_hdr points to the address of
1165 * the Optional IP Header. The address will be inlined in the PDB verbatim.
1166 * -for other values of OIHI options field, opt_ip_hdr is not used.
1167 * @cipherdata: pointer to block cipher transform definitions
1168 * Valid algorithm values - one of OP_PCL_IPSEC_*
1169 * @authdata: pointer to authentication transform definitions.
1170 * If an authentication key is required by the protocol, a "normal"
1171 * key must be provided; DKP (Derived Key Protocol) will be used to
1172 * compute MDHA on the fly in HW.
1173 * Valid algorithm values - one of OP_PCL_IPSEC_*
1175 * Note: L2 header copy functionality is implemented assuming that bits 14
1176 * (currently reserved) and 16-23 (part of Outer IP Header Material Length)
1177 * in DPOVRD register are not used (which is usually the case when L3 header
1178 * is provided in PDB).
1179 * When DPOVRD[14] is set, frame starts with an L2 header; in this case, the
1180 * L2 header length is found at DPOVRD[23:16]. SEC uses this length to copy
1181 * the header and then it deletes DPOVRD[23:16] (so there is no side effect
1182 * when later running IPsec protocol).
1184 * Return: size of descriptor written in words or negative number on error
1187 cnstr_shdsc_ipsec_new_encap(uint32_t *descbuf, bool ps,
1189 enum rta_share_type share,
1190 struct ipsec_encap_pdb *pdb,
1191 uint8_t *opt_ip_hdr,
1192 struct alginfo *cipherdata,
1193 struct alginfo *authdata)
1196 struct program *p = &prg;
1205 if (rta_sec_era < RTA_SEC_ERA_8) {
1206 pr_err("IPsec new mode encap: available only for Era %d or above\n",
1207 USER_SEC_ERA(RTA_SEC_ERA_8));
1211 PROGRAM_CNTXT_INIT(p, descbuf, 0);
1213 PROGRAM_SET_BSWAP(p);
1215 PROGRAM_SET_36BIT_ADDR(p);
1216 phdr = SHR_HDR(p, share, hdr, 0);
1218 __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
1220 switch (pdb->options & PDBOPTS_ESP_OIHI_MASK) {
1221 case PDBOPTS_ESP_OIHI_PDB_INL:
1222 COPY_DATA(p, opt_ip_hdr, pdb->ip_hdr_len);
1224 case PDBOPTS_ESP_OIHI_PDB_REF:
1226 COPY_DATA(p, opt_ip_hdr, 8);
1228 COPY_DATA(p, opt_ip_hdr, 4);
1235 MATHB(p, DPOVRD, AND, IPSEC_N_ENCAP_DPOVRD_L2_COPY, NONE, 4, IMMED2);
1236 pl2copy = JUMP(p, l2copy, LOCAL_JUMP, ALL_TRUE, MATH_Z);
1237 MATHI(p, DPOVRD, RSHIFT, IPSEC_N_ENCAP_DPOVRD_L2_LEN_SHIFT, VSEQOUTSZ,
1239 MATHB(p, DPOVRD, AND, ~IPSEC_N_ENCAP_DPOVRD_L2_LEN_MASK, DPOVRD, 4,
1241 /* TODO: CLASS2 corresponds to AUX=2'b10; add more intuitive defines */
1242 SEQFIFOSTORE(p, METADATA, 0, 0, CLASS2 | VLF);
1243 SET_LABEL(p, l2copy);
1245 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1246 if (authdata->keylen)
1247 __gen_auth_key(p, authdata);
1248 if (cipherdata->keylen)
1249 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1250 cipherdata->keylen, INLINE_KEY(cipherdata));
1251 SET_LABEL(p, keyjmp);
1252 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
1254 (uint16_t)(cipherdata->algtype | authdata->algtype));
1255 PATCH_JUMP(p, pl2copy, l2copy);
1256 PATCH_JUMP(p, pkeyjmp, keyjmp);
1257 PATCH_HDR(p, phdr, hdr);
1258 return PROGRAM_FINALIZE(p);
1262 * IPSEC_NEW_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor length
1264 * Accounts only for the "base" commands and is intended to be used by upper
1265 * layers to determine whether keys can be inlined or not. To be used as first
1266 * parameter of rta_inline_query().
1268 #define IPSEC_NEW_DEC_BASE_DESC_LEN (5 * CAAM_CMD_SZ + \
1269 sizeof(struct ipsec_decap_pdb))
1272 * IPSEC_NEW_NULL_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor
1273 * length for the case of
1274 * NULL decryption / authentication
1276 * Accounts only for the "base" commands and is intended to be used by upper
1277 * layers to determine whether key can be inlined or not. To be used as first
1278 * parameter of rta_inline_query().
1280 #define IPSEC_NEW_NULL_DEC_BASE_DESC_LEN (4 * CAAM_CMD_SZ + \
1281 sizeof(struct ipsec_decap_pdb))
1284 * cnstr_shdsc_ipsec_new_decap - IPSec new mode ESP decapsulation protocol-level
1285 * shared descriptor.
1286 * @descbuf: pointer to buffer used for descriptor construction
1287 * @ps: if 36/40bit addressing is desired, this parameter must be true
1288 * @swap: must be true when core endianness doesn't match SEC endianness
1289 * @share: sharing type of shared descriptor
1290 * @pdb: pointer to the PDB to be used with this descriptor
1291 * This structure will be copied inline to the descriptor under
1292 * construction. No error checking will be made. Refer to the
1293 * block guide for details about the decapsulation PDB.
1294 * @cipherdata: pointer to block cipher transform definitions
1295 * Valid algorithm values 0 one of OP_PCL_IPSEC_*
1296 * @authdata: pointer to authentication transform definitions.
1297 * If an authentication key is required by the protocol, a "normal"
1298 * key must be provided; DKP (Derived Key Protocol) will be used to
1299 * compute MDHA on the fly in HW.
1300 * Valid algorithm values - one of OP_PCL_IPSEC_*
1302 * Return: size of descriptor written in words or negative number on error
1305 cnstr_shdsc_ipsec_new_decap(uint32_t *descbuf, bool ps,
1307 enum rta_share_type share,
1308 struct ipsec_decap_pdb *pdb,
1309 struct alginfo *cipherdata,
1310 struct alginfo *authdata)
1313 struct program *p = &prg;
1320 if (rta_sec_era < RTA_SEC_ERA_8) {
1321 pr_err("IPsec new mode decap: available only for Era %d or above\n",
1322 USER_SEC_ERA(RTA_SEC_ERA_8));
1326 PROGRAM_CNTXT_INIT(p, descbuf, 0);
1328 PROGRAM_SET_BSWAP(p);
1330 PROGRAM_SET_36BIT_ADDR(p);
1331 phdr = SHR_HDR(p, share, hdr, 0);
1332 __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
1334 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1335 if (authdata->keylen)
1336 __gen_auth_key(p, authdata);
1337 if (cipherdata->keylen)
1338 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1339 cipherdata->keylen, INLINE_KEY(cipherdata));
1340 SET_LABEL(p, keyjmp);
1341 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
1343 (uint16_t)(cipherdata->algtype | authdata->algtype));
1344 PATCH_JUMP(p, pkeyjmp, keyjmp);
1345 PATCH_HDR(p, phdr, hdr);
1346 return PROGRAM_FINALIZE(p);
1350 * IPSEC_AUTH_VAR_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1351 * for the case of variable-length authentication
1353 * Note: Only for SoCs with SEC_ERA >= 3.
1355 * Accounts only for the "base" commands and is intended to be used by upper
1356 * layers to determine whether keys can be inlined or not. To be used as first
1357 * parameter of rta_inline_query().
1359 #define IPSEC_AUTH_VAR_BASE_DESC_LEN (27 * CAAM_CMD_SZ)
1362 * IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor
1363 * length for variable-length authentication only
1365 * Note: Only for SoCs with SEC_ERA >= 3.
1367 * Accounts only for the "base" commands and is intended to be used by upper
1368 * layers to determine whether key can be inlined or not. To be used as first
1369 * parameter of rta_inline_query().
1371 #define IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN \
1372 (IPSEC_AUTH_VAR_BASE_DESC_LEN + CAAM_CMD_SZ)
1375 * IPSEC_AUTH_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1377 * Accounts only for the "base" commands and is intended to be used by upper
1378 * layers to determine whether key can be inlined or not. To be used as first
1379 * parameter of rta_inline_query().
1381 #define IPSEC_AUTH_BASE_DESC_LEN (19 * CAAM_CMD_SZ)
1384 * IPSEC_AUTH_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor length
1386 * Accounts only for the "base" commands and is intended to be used by upper
1387 * layers to determine whether key can be inlined or not. To be used as first
1388 * parameter of rta_inline_query().
1390 #define IPSEC_AUTH_AES_DEC_BASE_DESC_LEN (IPSEC_AUTH_BASE_DESC_LEN + \
1394 * cnstr_shdsc_authenc - authenc-like descriptor
1395 * @descbuf: pointer to buffer used for descriptor construction
1396 * @ps: if 36/40bit addressing is desired, this parameter must be true
1397 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
1398 * @share: sharing type of shared descriptor
1399 * @cipherdata: pointer to block cipher transform definitions.
1400 * Valid algorithm values one of OP_ALG_ALGSEL_* {DES, 3DES, AES}
1402 * AES: OP_ALG_AAI_* {CBC, CTR}
1403 * DES, 3DES: OP_ALG_AAI_CBC
1404 * @authdata: pointer to authentication transform definitions.
1405 * Valid algorithm values - one of OP_ALG_ALGSEL_* {MD5, SHA1,
1406 * SHA224, SHA256, SHA384, SHA512}
1407 * Note: The key for authentication is supposed to be given as plain text.
1408 * Note: There's no support for keys longer than the block size of the
1409 * underlying hash function, according to the selected algorithm.
1411 * @ivlen: length of the IV to be read from the input frame, before any data
1414 * @trunc_len: the length of the ICV to be written to the output frame. If 0,
1415 * then the corresponding length of the digest, according to the
1416 * selected algorithm shall be used.
1417 * @dir: Protocol direction, encapsulation or decapsulation (DIR_ENC/DIR_DEC)
1419 * Note: Here's how the input frame needs to be formatted so that the processing
1420 * will be done correctly:
1421 * For encapsulation:
1423 * +----+----------------+-----------------------------------------------+
1424 * | IV | Auth-only head | Padded data to be auth & Enc | Auth-only tail |
1425 * +----+----------------+-----------------------------------------------+
1427 * +--------------------------------------+
1428 * | Authenticated & Encrypted data | ICV |
1429 * +--------------------------------+-----+
1431 * For decapsulation:
1433 * +----+----------------+-----------------+----------------------+
1434 * | IV | Auth-only head | Auth & Enc data | Auth-only tail | ICV |
1435 * +----+----------------+-----------------+----------------------+
1437 * +----+---------------------------+
1438 * | Decrypted & authenticated data |
1439 * +----+---------------------------+
1441 * Note: This descriptor can use per-packet commands, encoded as below in the
1444 * +------+------------------------------+
1445 * | 0x8 | auth_tail_len | auth_hdr_len |
1446 * +------+------------------------------+
1448 * This mechanism is available only for SoCs having SEC ERA >= 3. In other
1449 * words, this will not work for P4080TO2
1451 * Note: The descriptor does not add any kind of padding to the input data,
1452 * so the upper layer needs to ensure that the data is padded properly,
1453 * according to the selected cipher. Failure to do so will result in
1454 * the descriptor failing with a data-size error.
1456 * Return: size of descriptor written in words or negative number on error
1459 cnstr_shdsc_authenc(uint32_t *descbuf, bool ps, bool swap,
1460 enum rta_share_type share,
1461 struct alginfo *cipherdata,
1462 struct alginfo *authdata,
1464 uint8_t trunc_len, uint8_t dir)
1467 struct program *p = &prg;
1468 const bool need_dk = (dir == DIR_DEC) &&
1469 (cipherdata->algtype == OP_ALG_ALGSEL_AES) &&
1470 (cipherdata->algmode == OP_ALG_AAI_CBC);
1476 LABEL(no_auth_tail);
1478 REFERENCE(pskipkeys);
1479 REFERENCE(p_proc_icv);
1480 REFERENCE(p_no_auth_tail);
1482 PROGRAM_CNTXT_INIT(p, descbuf, 0);
1485 PROGRAM_SET_BSWAP(p);
1487 PROGRAM_SET_36BIT_ADDR(p);
1490 * Since we currently assume that key length is equal to hash digest
1491 * size, it's ok to truncate keylen value.
1493 trunc_len = trunc_len && (trunc_len < authdata->keylen) ?
1494 trunc_len : (uint8_t)authdata->keylen;
1496 SHR_HDR(p, share, 1, SC);
1498 /* Collect the (auth_tail || auth_hdr) len from DPOVRD */
1499 MATHB(p, DPOVRD, ADD, 0x80000000, MATH2, 4, IMMED2);
1501 /* Get auth_hdr len in MATH0 */
1502 MATHB(p, MATH2, AND, 0xFFFF, MATH0, 4, IMMED2);
1504 /* Get auth_tail len in MATH2 */
1505 MATHB(p, MATH2, AND, 0xFFF0000, MATH2, 4, IMMED2);
1506 MATHI(p, MATH2, RSHIFT, 16, MATH2, 4, IMMED2);
1508 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1510 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1511 INLINE_KEY(authdata));
1514 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1515 cipherdata->keylen, INLINE_KEY(cipherdata));
1518 ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC,
1519 OP_ALG_AS_INITFINAL,
1520 dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1524 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode,
1525 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1526 pskipkeys = JUMP(p, skipkeys, LOCAL_JUMP, ALL_TRUE, 0);
1528 SET_LABEL(p, keyjmp);
1530 ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
1531 OP_ALG_AS_INITFINAL,
1532 dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1536 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode |
1537 OP_ALG_AAI_DK, OP_ALG_AS_INITFINAL,
1538 ICV_CHECK_DISABLE, dir);
1539 SET_LABEL(p, skipkeys);
1541 SET_LABEL(p, skipkeys);
1542 ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
1543 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1547 if (cipherdata->algmode == OP_ALG_AAI_CTR)
1548 SEQLOAD(p, CONTEXT1, 16, ivlen, 0);
1550 SEQLOAD(p, CONTEXT1, 0, ivlen, 0);
1553 * authenticate auth_hdr data
1555 MATHB(p, MATH0, ADD, ZERO, VSEQINSZ, 4, 0);
1556 SEQFIFOLOAD(p, MSG2, 0, VLF);
1559 * Prepare the length of the data to be both encrypted/decrypted
1560 * and authenticated/checked
1562 MATHB(p, SEQINSZ, SUB, MATH2, VSEQINSZ, 4, 0);
1563 if (dir == DIR_DEC) {
1564 MATHB(p, VSEQINSZ, SUB, trunc_len, VSEQINSZ, 4, IMMED2);
1565 data_type = MSGINSNOOP;
1567 data_type = MSGOUTSNOOP;
1570 MATHB(p, VSEQINSZ, ADD, ZERO, VSEQOUTSZ, 4, 0);
1572 /* Prepare for writing the output frame */
1573 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1576 /* Check if there is no auth-tail */
1577 MATHB(p, MATH2, ADD, ZERO, MATH2, 4, 0);
1578 p_no_auth_tail = JUMP(p, no_auth_tail, LOCAL_JUMP, ALL_TRUE, MATH_Z);
1581 * Read input plain/cipher text, encrypt/decrypt & auth & write
1584 SEQFIFOLOAD(p, data_type, 0, VLF | LAST1 | FLUSH1);
1586 /* Authenticate auth tail */
1587 MATHB(p, MATH2, ADD, ZERO, VSEQINSZ, 4, 0);
1588 SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
1590 /* Jump to process icv */
1591 p_proc_icv = JUMP(p, proc_icv, LOCAL_JUMP, ALL_FALSE, MATH_Z);
1593 SET_LABEL(p, no_auth_tail);
1595 SEQFIFOLOAD(p, data_type, 0, VLF | LAST1 | LAST2 | FLUSH1);
1597 SET_LABEL(p, proc_icv);
1600 /* Finally, write the ICV */
1601 SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
1603 /* Read the ICV to check */
1604 SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
1606 PATCH_JUMP(p, pkeyjmp, keyjmp);
1607 PATCH_JUMP(p, pskipkeys, skipkeys);
1608 PATCH_JUMP(p, p_no_auth_tail, no_auth_tail);
1609 PATCH_JUMP(p, p_proc_icv, proc_icv);
1610 return PROGRAM_FINALIZE(p);
1613 #endif /* __DESC_IPSEC_H__ */