2 * This file is provided under a dual BSD/GPLv2 license. When using or
3 * redistributing this file, you may do so under either license.
7 * Copyright 2008-2016 Freescale Semiconductor Inc.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 * * Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * * Neither the name of the above-listed copyright holders nor the
18 * names of any contributors may be used to endorse or promote products
19 * derived from this software without specific prior written permission.
23 * ALTERNATIVELY, this software may be distributed under the terms of the
24 * GNU General Public License ("GPL") as published by the Free Software
25 * Foundation, either version 2 of that License or (at your option) any
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
41 #ifndef __DESC_IPSEC_H__
42 #define __DESC_IPSEC_H__
48 * DOC: IPsec Shared Descriptor Constructors
50 * Shared descriptors for IPsec protocol.
53 /* General IPSec ESP encap / decap PDB options */
56 * PDBOPTS_ESP_ESN - Extended sequence included
58 #define PDBOPTS_ESP_ESN 0x10
61 * PDBOPTS_ESP_IPVSN - Process IPv6 header
63 * Valid only for IPsec legacy mode.
65 #define PDBOPTS_ESP_IPVSN 0x02
68 * PDBOPTS_ESP_TUNNEL - Tunnel mode next-header byte
70 * Valid only for IPsec legacy mode.
72 #define PDBOPTS_ESP_TUNNEL 0x01
74 /* IPSec ESP Encap PDB options */
77 * PDBOPTS_ESP_UPDATE_CSUM - Update ip header checksum
79 * Valid only for IPsec legacy mode.
81 #define PDBOPTS_ESP_UPDATE_CSUM 0x80
84 * PDBOPTS_ESP_DIFFSERV - Copy TOS/TC from inner iphdr
86 * Valid only for IPsec legacy mode.
88 #define PDBOPTS_ESP_DIFFSERV 0x40
91 * PDBOPTS_ESP_IVSRC - IV comes from internal random gen
93 #define PDBOPTS_ESP_IVSRC 0x20
96 * PDBOPTS_ESP_IPHDRSRC - IP header comes from PDB
98 * Valid only for IPsec legacy mode.
100 #define PDBOPTS_ESP_IPHDRSRC 0x08
103 * PDBOPTS_ESP_INCIPHDR - Prepend IP header to output frame
105 * Valid only for IPsec legacy mode.
107 #define PDBOPTS_ESP_INCIPHDR 0x04
110 * PDBOPTS_ESP_OIHI_MASK - Mask for Outer IP Header Included
112 * Valid only for IPsec new mode.
114 #define PDBOPTS_ESP_OIHI_MASK 0x0c
117 * PDBOPTS_ESP_OIHI_PDB_INL - Prepend IP header to output frame from PDB (where
120 * Valid only for IPsec new mode.
122 #define PDBOPTS_ESP_OIHI_PDB_INL 0x0c
125 * PDBOPTS_ESP_OIHI_PDB_REF - Prepend IP header to output frame from PDB
126 * (referenced by pointer).
128 * Vlid only for IPsec new mode.
130 #define PDBOPTS_ESP_OIHI_PDB_REF 0x08
133 * PDBOPTS_ESP_OIHI_IF - Prepend IP header to output frame from input frame
135 * Valid only for IPsec new mode.
137 #define PDBOPTS_ESP_OIHI_IF 0x04
140 * PDBOPTS_ESP_NAT - Enable RFC 3948 UDP-encapsulated-ESP
142 * Valid only for IPsec new mode.
144 #define PDBOPTS_ESP_NAT 0x02
147 * PDBOPTS_ESP_NUC - Enable NAT UDP Checksum
149 * Valid only for IPsec new mode.
151 #define PDBOPTS_ESP_NUC 0x01
153 /* IPSec ESP Decap PDB options */
156 * PDBOPTS_ESP_ARS_MASK - antireplay window mask
158 #define PDBOPTS_ESP_ARS_MASK 0xc0
161 * PDBOPTS_ESP_ARSNONE - No antireplay window
163 #define PDBOPTS_ESP_ARSNONE 0x00
166 * PDBOPTS_ESP_ARS64 - 64-entry antireplay window
168 #define PDBOPTS_ESP_ARS64 0xc0
171 * PDBOPTS_ESP_ARS128 - 128-entry antireplay window
173 * Valid only for IPsec new mode.
175 #define PDBOPTS_ESP_ARS128 0x80
178 * PDBOPTS_ESP_ARS32 - 32-entry antireplay window
180 #define PDBOPTS_ESP_ARS32 0x40
183 * PDBOPTS_ESP_VERIFY_CSUM - Validate ip header checksum
185 * Valid only for IPsec legacy mode.
187 #define PDBOPTS_ESP_VERIFY_CSUM 0x20
190 * PDBOPTS_ESP_TECN - Implement RRFC6040 ECN tunneling from outer header to
193 * Valid only for IPsec new mode.
195 #define PDBOPTS_ESP_TECN 0x20
198 * PDBOPTS_ESP_OUTFMT - Output only decapsulation
200 * Valid only for IPsec legacy mode.
202 #define PDBOPTS_ESP_OUTFMT 0x08
205 * PDBOPTS_ESP_AOFL - Adjust out frame len
207 * Valid only for IPsec legacy mode and for SEC >= 5.3.
209 #define PDBOPTS_ESP_AOFL 0x04
212 * PDBOPTS_ESP_ETU - EtherType Update
214 * Add corresponding ethertype (0x0800 for IPv4, 0x86dd for IPv6) in the output
216 * Valid only for IPsec new mode.
218 #define PDBOPTS_ESP_ETU 0x01
220 #define PDBHMO_ESP_DECAP_SHIFT 28
221 #define PDBHMO_ESP_ENCAP_SHIFT 28
222 #define PDBNH_ESP_ENCAP_SHIFT 16
223 #define PDBNH_ESP_ENCAP_MASK (0xff << PDBNH_ESP_ENCAP_SHIFT)
224 #define PDBHDRLEN_ESP_DECAP_SHIFT 16
225 #define PDBHDRLEN_MASK (0x0fff << PDBHDRLEN_ESP_DECAP_SHIFT)
226 #define PDB_NH_OFFSET_SHIFT 8
227 #define PDB_NH_OFFSET_MASK (0xff << PDB_NH_OFFSET_SHIFT)
230 * PDBHMO_ESP_DECAP_DTTL - IPsec ESP decrement TTL (IPv4) / Hop limit (IPv6)
233 #define PDBHMO_ESP_DECAP_DTTL (0x02 << PDBHMO_ESP_DECAP_SHIFT)
236 * PDBHMO_ESP_ENCAP_DTTL - IPsec ESP increment TTL (IPv4) / Hop limit (IPv6)
239 #define PDBHMO_ESP_ENCAP_DTTL (0x02 << PDBHMO_ESP_ENCAP_SHIFT)
242 * PDBHMO_ESP_DIFFSERV - (Decap) DiffServ Copy - Copy the IPv4 TOS or IPv6
243 * Traffic Class byte from the outer IP header to the
246 #define PDBHMO_ESP_DIFFSERV (0x01 << PDBHMO_ESP_DECAP_SHIFT)
249 * PDBHMO_ESP_SNR - (Encap) - Sequence Number Rollover control
251 * Configures behaviour in case of SN / ESN rollover:
252 * error if SNR = 1, rollover allowed if SNR = 0.
253 * Valid only for IPsec new mode.
255 #define PDBHMO_ESP_SNR (0x01 << PDBHMO_ESP_ENCAP_SHIFT)
258 * PDBHMO_ESP_DFBIT - (Encap) Copy DF bit - if an IPv4 tunnel mode outer IP
259 * header is coming from the PDB, copy the DF bit from the
260 * inner IP header to the outer IP header.
262 #define PDBHMO_ESP_DFBIT (0x04 << PDBHMO_ESP_ENCAP_SHIFT)
265 * PDBHMO_ESP_DFV - (Decap) - DF bit value
267 * If ODF = 1, DF bit in output frame is replaced by DFV.
268 * Valid only from SEC Era 5 onwards.
270 #define PDBHMO_ESP_DFV (0x04 << PDBHMO_ESP_DECAP_SHIFT)
273 * PDBHMO_ESP_ODF - (Decap) Override DF bit in IPv4 header of decapsulated
276 * If ODF = 1, DF is replaced with the value of DFV bit.
277 * Valid only from SEC Era 5 onwards.
279 #define PDBHMO_ESP_ODF (0x08 << PDBHMO_ESP_DECAP_SHIFT)
282 * struct ipsec_encap_cbc - PDB part for IPsec CBC encapsulation
283 * @iv: 16-byte array initialization vector
285 struct ipsec_encap_cbc {
291 * struct ipsec_encap_ctr - PDB part for IPsec CTR encapsulation
292 * @ctr_nonce: 4-byte array nonce
293 * @ctr_initial: initial count constant
294 * @iv: initialization vector
296 struct ipsec_encap_ctr {
297 uint8_t ctr_nonce[4];
298 uint32_t ctr_initial;
303 * struct ipsec_encap_ccm - PDB part for IPsec CCM encapsulation
304 * @salt: 3-byte array salt (lower 24 bits)
305 * @ccm_opt: CCM algorithm options - MSB-LSB description:
306 * b0_flags (8b) - CCM B0; use 0x5B for 8-byte ICV, 0x6B for 12-byte ICV,
307 * 0x7B for 16-byte ICV (cf. RFC4309, RFC3610)
308 * ctr_flags (8b) - counter flags; constant equal to 0x3
309 * ctr_initial (16b) - initial count constant
310 * @iv: initialization vector
312 struct ipsec_encap_ccm {
319 * struct ipsec_encap_gcm - PDB part for IPsec GCM encapsulation
320 * @salt: 3-byte array salt (lower 24 bits)
321 * @rsvd: reserved, do not use
322 * @iv: initialization vector
324 struct ipsec_encap_gcm {
331 * struct ipsec_encap_pdb - PDB for IPsec encapsulation
332 * @options: MSB-LSB description (both for legacy and new modes)
333 * hmo (header manipulation options) - 4b
335 * next header (legacy) / reserved (new) - 8b
336 * next header offset (legacy) / AOIPHO (actual outer IP header offset) - 8b
337 * option flags (depend on selected algorithm) - 8b
338 * @seq_num_ext_hi: (optional) IPsec Extended Sequence Number (ESN)
339 * @seq_num: IPsec sequence number
340 * @spi: IPsec SPI (Security Parameters Index)
341 * @ip_hdr_len: optional IP Header length (in bytes)
343 * Opt. IP Hdr Len - 16b
344 * @ip_hdr: optional IP Header content (only for IPsec legacy mode)
346 struct ipsec_encap_pdb {
348 uint32_t seq_num_ext_hi;
351 struct ipsec_encap_cbc cbc;
352 struct ipsec_encap_ctr ctr;
353 struct ipsec_encap_ccm ccm;
354 struct ipsec_encap_gcm gcm;
361 static inline unsigned int
362 __rta_copy_ipsec_encap_pdb(struct program *program,
363 struct ipsec_encap_pdb *pdb,
366 unsigned int start_pc = program->current_pc;
368 __rta_out32(program, pdb->options);
369 __rta_out32(program, pdb->seq_num_ext_hi);
370 __rta_out32(program, pdb->seq_num);
372 switch (algtype & OP_PCL_IPSEC_CIPHER_MASK) {
373 case OP_PCL_IPSEC_DES_IV64:
374 case OP_PCL_IPSEC_DES:
375 case OP_PCL_IPSEC_3DES:
376 case OP_PCL_IPSEC_AES_CBC:
377 case OP_PCL_IPSEC_NULL:
378 rta_copy_data(program, pdb->cbc.iv, sizeof(pdb->cbc.iv));
381 case OP_PCL_IPSEC_AES_CTR:
382 rta_copy_data(program, pdb->ctr.ctr_nonce,
383 sizeof(pdb->ctr.ctr_nonce));
384 __rta_out32(program, pdb->ctr.ctr_initial);
385 __rta_out64(program, true, pdb->ctr.iv);
388 case OP_PCL_IPSEC_AES_CCM8:
389 case OP_PCL_IPSEC_AES_CCM12:
390 case OP_PCL_IPSEC_AES_CCM16:
391 rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
392 __rta_out32(program, pdb->ccm.ccm_opt);
393 __rta_out64(program, true, pdb->ccm.iv);
396 case OP_PCL_IPSEC_AES_GCM8:
397 case OP_PCL_IPSEC_AES_GCM12:
398 case OP_PCL_IPSEC_AES_GCM16:
399 case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
400 rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
401 __rta_out32(program, pdb->gcm.rsvd);
402 __rta_out64(program, true, pdb->gcm.iv);
406 __rta_out32(program, pdb->spi);
407 __rta_out32(program, pdb->ip_hdr_len);
413 * struct ipsec_decap_cbc - PDB part for IPsec CBC decapsulation
414 * @rsvd: reserved, do not use
416 struct ipsec_decap_cbc {
421 * struct ipsec_decap_ctr - PDB part for IPsec CTR decapsulation
422 * @ctr_nonce: 4-byte array nonce
423 * @ctr_initial: initial count constant
425 struct ipsec_decap_ctr {
426 uint8_t ctr_nonce[4];
427 uint32_t ctr_initial;
431 * struct ipsec_decap_ccm - PDB part for IPsec CCM decapsulation
432 * @salt: 3-byte salt (lower 24 bits)
433 * @ccm_opt: CCM algorithm options - MSB-LSB description:
434 * b0_flags (8b) - CCM B0; use 0x5B for 8-byte ICV, 0x6B for 12-byte ICV,
435 * 0x7B for 16-byte ICV (cf. RFC4309, RFC3610)
436 * ctr_flags (8b) - counter flags; constant equal to 0x3
437 * ctr_initial (16b) - initial count constant
439 struct ipsec_decap_ccm {
445 * struct ipsec_decap_gcm - PDB part for IPsec GCN decapsulation
447 * @rsvd: reserved, do not use
449 struct ipsec_decap_gcm {
455 * struct ipsec_decap_pdb - PDB for IPsec decapsulation
456 * @options: MSB-LSB description (both for legacy and new modes)
457 * hmo (header manipulation options) - 4b
458 * IP header length - 12b
459 * next header offset (legacy) / AOIPHO (actual outer IP header offset) - 8b
460 * option flags (depend on selected algorithm) - 8b
461 * @seq_num_ext_hi: (optional) IPsec Extended Sequence Number (ESN)
462 * @seq_num: IPsec sequence number
463 * @anti_replay: Anti-replay window; size depends on ARS (option flags);
464 * format must be Big Endian, irrespective of platform
466 struct ipsec_decap_pdb {
469 struct ipsec_decap_cbc cbc;
470 struct ipsec_decap_ctr ctr;
471 struct ipsec_decap_ccm ccm;
472 struct ipsec_decap_gcm gcm;
474 uint32_t seq_num_ext_hi;
476 uint32_t anti_replay[4];
479 static inline unsigned int
480 __rta_copy_ipsec_decap_pdb(struct program *program,
481 struct ipsec_decap_pdb *pdb,
484 unsigned int start_pc = program->current_pc;
487 __rta_out32(program, pdb->options);
489 switch (algtype & OP_PCL_IPSEC_CIPHER_MASK) {
490 case OP_PCL_IPSEC_DES_IV64:
491 case OP_PCL_IPSEC_DES:
492 case OP_PCL_IPSEC_3DES:
493 case OP_PCL_IPSEC_AES_CBC:
494 case OP_PCL_IPSEC_NULL:
495 __rta_out32(program, pdb->cbc.rsvd[0]);
496 __rta_out32(program, pdb->cbc.rsvd[1]);
499 case OP_PCL_IPSEC_AES_CTR:
500 rta_copy_data(program, pdb->ctr.ctr_nonce,
501 sizeof(pdb->ctr.ctr_nonce));
502 __rta_out32(program, pdb->ctr.ctr_initial);
505 case OP_PCL_IPSEC_AES_CCM8:
506 case OP_PCL_IPSEC_AES_CCM12:
507 case OP_PCL_IPSEC_AES_CCM16:
508 rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
509 __rta_out32(program, pdb->ccm.ccm_opt);
512 case OP_PCL_IPSEC_AES_GCM8:
513 case OP_PCL_IPSEC_AES_GCM12:
514 case OP_PCL_IPSEC_AES_GCM16:
515 case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
516 rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
517 __rta_out32(program, pdb->gcm.rsvd);
521 __rta_out32(program, pdb->seq_num_ext_hi);
522 __rta_out32(program, pdb->seq_num);
524 switch (pdb->options & PDBOPTS_ESP_ARS_MASK) {
525 case PDBOPTS_ESP_ARS128:
528 case PDBOPTS_ESP_ARS64:
531 case PDBOPTS_ESP_ARS32:
534 case PDBOPTS_ESP_ARSNONE:
540 for (i = 0; i < ars; i++)
541 __rta_out_be32(program, pdb->anti_replay[i]);
547 * enum ipsec_icv_size - Type selectors for icv size in IPsec protocol
548 * @IPSEC_ICV_MD5_SIZE: full-length MD5 ICV
549 * @IPSEC_ICV_MD5_TRUNC_SIZE: truncated MD5 ICV
551 enum ipsec_icv_size {
552 IPSEC_ICV_MD5_SIZE = 16,
553 IPSEC_ICV_MD5_TRUNC_SIZE = 12
557 * IPSec ESP Datapath Protocol Override Register (DPOVRD)
560 #define IPSEC_DECO_DPOVRD_USE 0x80
562 struct ipsec_deco_dpovrd {
567 uint8_t next_header; /* next header if encap */
568 uint8_t rsvd; /* reserved if decap */
572 struct ipsec_new_encap_deco_dpovrd {
573 #define IPSEC_NEW_ENCAP_DECO_DPOVRD_USE 0x8000
574 uint16_t ovrd_ip_hdr_len; /* OVRD + outer IP header material
577 #define IPSEC_NEW_ENCAP_OIMIF 0x80
578 uint8_t oimif_aoipho; /* OIMIF + actual outer IP header
584 struct ipsec_new_decap_deco_dpovrd {
586 uint8_t aoipho_hi; /* upper nibble of actual outer IP
589 uint16_t aoipho_lo_ip_hdr_len; /* lower nibble of actual outer IP
590 * header + outer IP header material
595 __gen_auth_key(struct program *program, struct alginfo *authdata)
599 switch (authdata->algtype & OP_PCL_IPSEC_AUTH_MASK) {
600 case OP_PCL_IPSEC_HMAC_MD5_96:
601 case OP_PCL_IPSEC_HMAC_MD5_128:
602 dkp_protid = OP_PCLID_DKP_MD5;
604 case OP_PCL_IPSEC_HMAC_SHA1_96:
605 case OP_PCL_IPSEC_HMAC_SHA1_160:
606 dkp_protid = OP_PCLID_DKP_SHA1;
608 case OP_PCL_IPSEC_HMAC_SHA2_256_128:
609 dkp_protid = OP_PCLID_DKP_SHA256;
611 case OP_PCL_IPSEC_HMAC_SHA2_384_192:
612 dkp_protid = OP_PCLID_DKP_SHA384;
614 case OP_PCL_IPSEC_HMAC_SHA2_512_256:
615 dkp_protid = OP_PCLID_DKP_SHA512;
618 KEY(program, KEY2, authdata->key_enc_flags, authdata->key,
619 authdata->keylen, INLINE_KEY(authdata));
623 if (authdata->key_type == RTA_DATA_PTR)
624 DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_PTR,
625 OP_PCL_DKP_DST_PTR, (uint16_t)authdata->keylen,
626 authdata->key, authdata->key_type);
628 DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_IMM,
629 OP_PCL_DKP_DST_IMM, (uint16_t)authdata->keylen,
630 authdata->key, authdata->key_type);
634 * cnstr_shdsc_ipsec_encap - IPSec ESP encapsulation protocol-level shared
636 * @descbuf: pointer to buffer used for descriptor construction
637 * @ps: if 36/40bit addressing is desired, this parameter must be true
638 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
639 * @pdb: pointer to the PDB to be used with this descriptor
640 * This structure will be copied inline to the descriptor under
641 * construction. No error checking will be made. Refer to the
642 * block guide for a details of the encapsulation PDB.
643 * @cipherdata: pointer to block cipher transform definitions
644 * Valid algorithm values - one of OP_PCL_IPSEC_*
645 * @authdata: pointer to authentication transform definitions
646 * If an authentication key is required by the protocol:
647 * -For SEC Eras 1-5, an MDHA split key must be provided;
648 * Note that the size of the split key itself must be specified.
649 * -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
650 * Key Protocol) will be used to compute MDHA on the fly in HW.
651 * Valid algorithm values - one of OP_PCL_IPSEC_*
653 * Return: size of descriptor written in words or negative number on error
656 cnstr_shdsc_ipsec_encap(uint32_t *descbuf, bool ps, bool swap,
657 struct ipsec_encap_pdb *pdb,
658 struct alginfo *cipherdata,
659 struct alginfo *authdata)
662 struct program *p = &prg;
669 PROGRAM_CNTXT_INIT(p, descbuf, 0);
671 PROGRAM_SET_BSWAP(p);
673 PROGRAM_SET_36BIT_ADDR(p);
674 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
675 __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
676 COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
678 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
679 if (authdata->keylen) {
680 if (rta_sec_era < RTA_SEC_ERA_6)
681 KEY(p, MDHA_SPLIT_KEY, authdata->key_enc_flags,
682 authdata->key, authdata->keylen,
683 INLINE_KEY(authdata));
685 __gen_auth_key(p, authdata);
687 if (cipherdata->keylen)
688 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
689 cipherdata->keylen, INLINE_KEY(cipherdata));
690 SET_LABEL(p, keyjmp);
691 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
693 (uint16_t)(cipherdata->algtype | authdata->algtype));
694 PATCH_JUMP(p, pkeyjmp, keyjmp);
695 PATCH_HDR(p, phdr, hdr);
696 return PROGRAM_FINALIZE(p);
700 * cnstr_shdsc_ipsec_decap - IPSec ESP decapsulation protocol-level shared
702 * @descbuf: pointer to buffer used for descriptor construction
703 * @ps: if 36/40bit addressing is desired, this parameter must be true
704 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
705 * @pdb: pointer to the PDB to be used with this descriptor
706 * This structure will be copied inline to the descriptor under
707 * construction. No error checking will be made. Refer to the
708 * block guide for details about the decapsulation PDB.
709 * @cipherdata: pointer to block cipher transform definitions.
710 * Valid algorithm values - one of OP_PCL_IPSEC_*
711 * @authdata: pointer to authentication transform definitions
712 * If an authentication key is required by the protocol:
713 * -For SEC Eras 1-5, an MDHA split key must be provided;
714 * Note that the size of the split key itself must be specified.
715 * -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
716 * Key Protocol) will be used to compute MDHA on the fly in HW.
717 * Valid algorithm values - one of OP_PCL_IPSEC_*
719 * Return: size of descriptor written in words or negative number on error
722 cnstr_shdsc_ipsec_decap(uint32_t *descbuf, bool ps, bool swap,
723 struct ipsec_decap_pdb *pdb,
724 struct alginfo *cipherdata,
725 struct alginfo *authdata)
728 struct program *p = &prg;
735 PROGRAM_CNTXT_INIT(p, descbuf, 0);
737 PROGRAM_SET_BSWAP(p);
739 PROGRAM_SET_36BIT_ADDR(p);
740 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
741 __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
743 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
744 if (authdata->keylen) {
745 if (rta_sec_era < RTA_SEC_ERA_6)
746 KEY(p, MDHA_SPLIT_KEY, authdata->key_enc_flags,
747 authdata->key, authdata->keylen,
748 INLINE_KEY(authdata));
750 __gen_auth_key(p, authdata);
752 if (cipherdata->keylen)
753 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
754 cipherdata->keylen, INLINE_KEY(cipherdata));
755 SET_LABEL(p, keyjmp);
756 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
758 (uint16_t)(cipherdata->algtype | authdata->algtype));
759 PATCH_JUMP(p, pkeyjmp, keyjmp);
760 PATCH_HDR(p, phdr, hdr);
761 return PROGRAM_FINALIZE(p);
765 * cnstr_shdsc_ipsec_encap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
766 * AES-XCBC-MAC-96 ESP encapsulation shared descriptor.
767 * @descbuf: pointer to buffer used for descriptor construction
768 * @pdb: pointer to the PDB to be used with this descriptor
769 * This structure will be copied inline to the descriptor under
770 * construction. No error checking will be made. Refer to the
771 * block guide for a details of the encapsulation PDB.
772 * @cipherdata: pointer to block cipher transform definitions
773 * Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
774 * @authdata: pointer to authentication transform definitions
775 * Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
777 * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
778 * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
779 * Outer/Transport IP Header is present in the encapsulation output packet.
780 * The descriptor performs DES-CBC/3DES-CBC & HMAC-MD5-96 and then rereads
781 * the input packet to do the AES-XCBC-MAC-96 calculation and to overwrite
783 * The descriptor uses all the benefits of the built-in protocol by computing
784 * the IPsec ESP with a hardware supported algorithms combination
785 * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
786 * was chosen in order to speed up the computational time for this intermediate
788 * Warning: The user must allocate at least 32 bytes for the authentication key
789 * (in order to use it also with HMAC-MD5-96),even when using a shorter key
790 * for the AES-XCBC-MAC-96.
792 * Return: size of descriptor written in words or negative number on error
795 cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
796 struct ipsec_encap_pdb *pdb,
797 struct alginfo *cipherdata,
798 struct alginfo *authdata)
801 struct program *p = &prg;
807 LABEL(swapped_seqin_fields);
808 LABEL(swapped_seqin_ptr);
811 REFERENCE(move_outlen);
812 REFERENCE(move_seqout_ptr);
813 REFERENCE(swapped_seqin_ptr_jump);
814 REFERENCE(write_swapped_seqin_ptr);
816 PROGRAM_CNTXT_INIT(p, descbuf, 0);
817 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
818 __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
819 COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
821 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
823 * Hard-coded KEY arguments. The descriptor uses all the benefits of
824 * the built-in protocol by computing the IPsec ESP with a hardware
825 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
826 * The HMAC-MD5 authentication algorithm was chosen with
827 * the keys options from below in order to speed up the computational
828 * time for this intermediate step.
829 * Warning: The user must allocate at least 32 bytes for
830 * the authentication key (in order to use it also with HMAC-MD5-96),
831 * even when using a shorter key for the AES-XCBC-MAC-96.
833 KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
834 SET_LABEL(p, keyjump);
835 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
836 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
838 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
839 cipherdata->keylen, INLINE_KEY(cipherdata));
840 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL, OP_PCLID_IPSEC,
841 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
842 /* Swap SEQINPTR to SEQOUTPTR. */
843 move_seqout_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
844 MATHB(p, MATH1, AND, ~(CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR), MATH1,
847 * TODO: RTA currently doesn't support creating a LOAD command
848 * with another command as IMM.
849 * To be changed when proper support is added in RTA.
851 LOAD(p, 0xa00000e5, MATH3, 4, 4, IMMED);
852 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
853 write_swapped_seqin_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
855 swapped_seqin_ptr_jump = JUMP(p, swapped_seqin_ptr, LOCAL_JUMP,
857 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
858 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
860 SEQOUTPTR(p, 0, 65535, RTO);
861 move_outlen = MOVE(p, DESCBUF, 0, MATH0, 4, 8, WAITCOMP | IMMED);
863 (uint64_t)(pdb->ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE),
864 VSEQINSZ, 4, IMMED2);
865 MATHB(p, MATH0, SUB, IPSEC_ICV_MD5_TRUNC_SIZE, VSEQOUTSZ, 4, IMMED2);
866 KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
868 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
869 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
870 SEQFIFOLOAD(p, SKIP, pdb->ip_hdr_len, 0);
871 SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1 | LAST1);
872 SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
873 SEQSTORE(p, CONTEXT1, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
875 * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
876 * To be changed when proper support is added in RTA.
878 /* Label the Shared Descriptor Pointer */
879 SET_LABEL(p, shd_ptr);
881 /* Label the Output Pointer */
882 SET_LABEL(p, outptr);
884 /* Label the first word after JD */
885 SET_LABEL(p, swapped_seqin_fields);
886 swapped_seqin_fields += 8;
887 /* Label the second word after JD */
888 SET_LABEL(p, swapped_seqin_ptr);
889 swapped_seqin_ptr += 9;
891 PATCH_HDR(p, phdr, hdr);
892 PATCH_JUMP(p, pkeyjump, keyjump);
893 PATCH_JUMP(p, swapped_seqin_ptr_jump, swapped_seqin_ptr);
894 PATCH_MOVE(p, move_outlen, outptr);
895 PATCH_MOVE(p, move_seqout_ptr, shd_ptr);
896 PATCH_MOVE(p, write_swapped_seqin_ptr, swapped_seqin_fields);
897 return PROGRAM_FINALIZE(p);
901 * cnstr_shdsc_ipsec_decap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
902 * AES-XCBC-MAC-96 ESP decapsulation shared descriptor.
903 * @descbuf: pointer to buffer used for descriptor construction
904 * @pdb: pointer to the PDB to be used with this descriptor
905 * This structure will be copied inline to the descriptor under
906 * construction. No error checking will be made. Refer to the
907 * block guide for a details of the encapsulation PDB.
908 * @cipherdata: pointer to block cipher transform definitions
909 * Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
910 * @authdata: pointer to authentication transform definitions
911 * Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
913 * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
914 * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
915 * Outer/Transport IP Header is present in the decapsulation input packet.
916 * The descriptor computes the AES-XCBC-MAC-96 to check if the received ICV
917 * is correct, rereads the input packet to compute the MD5 ICV, overwrites
918 * the XCBC ICV, and then sends the modified input packet to the
919 * DES-CBC/3DES-CBC & HMAC-MD5-96 IPsec.
920 * The descriptor uses all the benefits of the built-in protocol by computing
921 * the IPsec ESP with a hardware supported algorithms combination
922 * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
923 * was chosen in order to speed up the computational time for this intermediate
925 * Warning: The user must allocate at least 32 bytes for the authentication key
926 * (in order to use it also with HMAC-MD5-96),even when using a shorter key
927 * for the AES-XCBC-MAC-96.
929 * Return: size of descriptor written in words or negative number on error
932 cnstr_shdsc_ipsec_decap_des_aes_xcbc(uint32_t *descbuf,
933 struct ipsec_decap_pdb *pdb,
934 struct alginfo *cipherdata,
935 struct alginfo *authdata)
938 struct program *p = &prg;
939 uint32_t ip_hdr_len = (pdb->options & PDBHDRLEN_MASK) >>
940 PDBHDRLEN_ESP_DECAP_SHIFT;
948 LABEL(swapped_seqout_fields);
949 LABEL(swapped_seqout_ptr);
950 REFERENCE(seqout_ptr_jump);
953 REFERENCE(move_jump);
954 REFERENCE(move_jump_back);
955 REFERENCE(move_seqin_ptr);
956 REFERENCE(swapped_seqout_ptr_jump);
957 REFERENCE(write_swapped_seqout_ptr);
959 PROGRAM_CNTXT_INIT(p, descbuf, 0);
960 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
961 __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
963 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
965 * Hard-coded KEY arguments. The descriptor uses all the benefits of
966 * the built-in protocol by computing the IPsec ESP with a hardware
967 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
968 * The HMAC-MD5 authentication algorithm was chosen with
969 * the keys options from bellow in order to speed up the computational
970 * time for this intermediate step.
971 * Warning: The user must allocate at least 32 bytes for
972 * the authentication key (in order to use it also with HMAC-MD5-96),
973 * even when using a shorter key for the AES-XCBC-MAC-96.
975 KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
976 SET_LABEL(p, keyjump);
977 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
978 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
980 KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
981 INLINE_KEY(authdata));
982 MATHB(p, SEQINSZ, SUB,
983 (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), MATH0, 4,
985 MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
986 ALG_OPERATION(p, OP_ALG_ALGSEL_MD5, OP_ALG_AAI_HMAC_PRECOMP,
987 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
988 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
989 OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
990 SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
991 SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1);
992 SEQFIFOLOAD(p, ICV1, IPSEC_ICV_MD5_TRUNC_SIZE, FLUSH1 | LAST1);
993 /* Swap SEQOUTPTR to SEQINPTR. */
994 move_seqin_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
995 MATHB(p, MATH1, OR, CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR, MATH1, 8,
998 * TODO: RTA currently doesn't support creating a LOAD command
999 * with another command as IMM.
1000 * To be changed when proper support is added in RTA.
1002 LOAD(p, 0xA00000e1, MATH3, 4, 4, IMMED);
1003 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
1004 write_swapped_seqout_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
1006 swapped_seqout_ptr_jump = JUMP(p, swapped_seqout_ptr, LOCAL_JUMP,
1009 * TODO: To be changed when proper support is added in RTA (can't load
1010 * a command that is also written by RTA).
1011 * Change when proper RTA support is added.
1013 SET_LABEL(p, jump_cmd);
1014 WORD(p, 0xA00000f3);
1015 SEQINPTR(p, 0, 65535, RTO);
1016 MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
1017 MATHB(p, MATH0, ADD, ip_hdr_len, VSEQOUTSZ, 4, IMMED2);
1018 move_jump = MOVE(p, DESCBUF, 0, OFIFO, 0, 8, WAITCOMP | IMMED);
1019 move_jump_back = MOVE(p, OFIFO, 0, DESCBUF, 0, 8, IMMED);
1020 SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
1021 SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
1022 SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
1023 SEQSTORE(p, CONTEXT2, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
1024 seqout_ptr_jump = JUMP(p, seqout_ptr, LOCAL_JUMP, ALL_TRUE, CALM);
1026 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
1027 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_CLR_C2MODE |
1028 CLRW_CLR_C2DATAS | CLRW_CLR_C2CTX | CLRW_RESET_CLS1_CHA, CLRW, 0,
1030 SEQINPTR(p, 0, 65535, RTO);
1031 MATHB(p, MATH0, ADD,
1032 (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), SEQINSZ, 4,
1034 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1035 cipherdata->keylen, INLINE_KEY(cipherdata));
1036 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL, OP_PCLID_IPSEC,
1037 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
1039 * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
1040 * To be changed when proper support is added in RTA.
1042 /* Label the SEQ OUT PTR */
1043 SET_LABEL(p, seqout_ptr);
1045 /* Label the Output Length */
1046 SET_LABEL(p, outlen);
1048 /* Label the SEQ IN PTR */
1049 SET_LABEL(p, seqin_ptr);
1051 /* Label the first word after JD */
1052 SET_LABEL(p, swapped_seqout_fields);
1053 swapped_seqout_fields += 8;
1054 /* Label the second word after JD */
1055 SET_LABEL(p, swapped_seqout_ptr);
1056 swapped_seqout_ptr += 9;
1058 PATCH_HDR(p, phdr, hdr);
1059 PATCH_JUMP(p, pkeyjump, keyjump);
1060 PATCH_JUMP(p, seqout_ptr_jump, seqout_ptr);
1061 PATCH_JUMP(p, swapped_seqout_ptr_jump, swapped_seqout_ptr);
1062 PATCH_MOVE(p, move_jump, jump_cmd);
1063 PATCH_MOVE(p, move_jump_back, seqin_ptr);
1064 PATCH_MOVE(p, move_seqin_ptr, outlen);
1065 PATCH_MOVE(p, write_swapped_seqout_ptr, swapped_seqout_fields);
1066 return PROGRAM_FINALIZE(p);
1070 * IPSEC_NEW_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor length
1072 * Accounts only for the "base" commands and is intended to be used by upper
1073 * layers to determine whether Outer IP Header and/or keys can be inlined or
1074 * not. To be used as first parameter of rta_inline_query().
1076 #define IPSEC_NEW_ENC_BASE_DESC_LEN (5 * CAAM_CMD_SZ + \
1077 sizeof(struct ipsec_encap_pdb))
1080 * IPSEC_NEW_NULL_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor
1081 * length for the case of
1082 * NULL encryption / authentication
1084 * Accounts only for the "base" commands and is intended to be used by upper
1085 * layers to determine whether Outer IP Header and/or key can be inlined or
1086 * not. To be used as first parameter of rta_inline_query().
1088 #define IPSEC_NEW_NULL_ENC_BASE_DESC_LEN (4 * CAAM_CMD_SZ + \
1089 sizeof(struct ipsec_encap_pdb))
1092 * cnstr_shdsc_ipsec_new_encap - IPSec new mode ESP encapsulation
1093 * protocol-level shared descriptor.
1094 * @descbuf: pointer to buffer used for descriptor construction
1095 * @ps: if 36/40bit addressing is desired, this parameter must be true
1096 * @swap: must be true when core endianness doesn't match SEC endianness
1097 * @pdb: pointer to the PDB to be used with this descriptor
1098 * This structure will be copied inline to the descriptor under
1099 * construction. No error checking will be made. Refer to the
1100 * block guide for details about the encapsulation PDB.
1101 * @opt_ip_hdr: pointer to Optional IP Header
1102 * -if OIHI = PDBOPTS_ESP_OIHI_PDB_INL, opt_ip_hdr points to the buffer to
1103 * be inlined in the PDB. Number of bytes (buffer size) copied is provided
1104 * in pdb->ip_hdr_len.
1105 * -if OIHI = PDBOPTS_ESP_OIHI_PDB_REF, opt_ip_hdr points to the address of
1106 * the Optional IP Header. The address will be inlined in the PDB verbatim.
1107 * -for other values of OIHI options field, opt_ip_hdr is not used.
1108 * @cipherdata: pointer to block cipher transform definitions
1109 * Valid algorithm values - one of OP_PCL_IPSEC_*
1110 * @authdata: pointer to authentication transform definitions.
1111 * If an authentication key is required by the protocol, a "normal"
1112 * key must be provided; DKP (Derived Key Protocol) will be used to
1113 * compute MDHA on the fly in HW.
1114 * Valid algorithm values - one of OP_PCL_IPSEC_*
1116 * Return: size of descriptor written in words or negative number on error
1119 cnstr_shdsc_ipsec_new_encap(uint32_t *descbuf, bool ps,
1121 struct ipsec_encap_pdb *pdb,
1122 uint8_t *opt_ip_hdr,
1123 struct alginfo *cipherdata,
1124 struct alginfo *authdata)
1127 struct program *p = &prg;
1134 if (rta_sec_era < RTA_SEC_ERA_8) {
1135 pr_err("IPsec new mode encap: available only for Era %d or above\n",
1136 USER_SEC_ERA(RTA_SEC_ERA_8));
1140 PROGRAM_CNTXT_INIT(p, descbuf, 0);
1142 PROGRAM_SET_BSWAP(p);
1144 PROGRAM_SET_36BIT_ADDR(p);
1145 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
1147 __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
1149 switch (pdb->options & PDBOPTS_ESP_OIHI_MASK) {
1150 case PDBOPTS_ESP_OIHI_PDB_INL:
1151 COPY_DATA(p, opt_ip_hdr, pdb->ip_hdr_len);
1153 case PDBOPTS_ESP_OIHI_PDB_REF:
1155 COPY_DATA(p, opt_ip_hdr, 8);
1157 COPY_DATA(p, opt_ip_hdr, 4);
1164 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1165 if (authdata->keylen)
1166 __gen_auth_key(p, authdata);
1167 if (cipherdata->keylen)
1168 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1169 cipherdata->keylen, INLINE_KEY(cipherdata));
1170 SET_LABEL(p, keyjmp);
1171 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
1173 (uint16_t)(cipherdata->algtype | authdata->algtype));
1174 PATCH_JUMP(p, pkeyjmp, keyjmp);
1175 PATCH_HDR(p, phdr, hdr);
1176 return PROGRAM_FINALIZE(p);
1180 * IPSEC_NEW_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor length
1182 * Accounts only for the "base" commands and is intended to be used by upper
1183 * layers to determine whether keys can be inlined or not. To be used as first
1184 * parameter of rta_inline_query().
1186 #define IPSEC_NEW_DEC_BASE_DESC_LEN (5 * CAAM_CMD_SZ + \
1187 sizeof(struct ipsec_decap_pdb))
1190 * IPSEC_NEW_NULL_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor
1191 * length for the case of
1192 * NULL decryption / authentication
1194 * Accounts only for the "base" commands and is intended to be used by upper
1195 * layers to determine whether key can be inlined or not. To be used as first
1196 * parameter of rta_inline_query().
1198 #define IPSEC_NEW_NULL_DEC_BASE_DESC_LEN (4 * CAAM_CMD_SZ + \
1199 sizeof(struct ipsec_decap_pdb))
1202 * cnstr_shdsc_ipsec_new_decap - IPSec new mode ESP decapsulation protocol-level
1203 * shared descriptor.
1204 * @descbuf: pointer to buffer used for descriptor construction
1205 * @ps: if 36/40bit addressing is desired, this parameter must be true
1206 * @swap: must be true when core endianness doesn't match SEC endianness
1207 * @pdb: pointer to the PDB to be used with this descriptor
1208 * This structure will be copied inline to the descriptor under
1209 * construction. No error checking will be made. Refer to the
1210 * block guide for details about the decapsulation PDB.
1211 * @cipherdata: pointer to block cipher transform definitions
1212 * Valid algorithm values 0 one of OP_PCL_IPSEC_*
1213 * @authdata: pointer to authentication transform definitions.
1214 * If an authentication key is required by the protocol, a "normal"
1215 * key must be provided; DKP (Derived Key Protocol) will be used to
1216 * compute MDHA on the fly in HW.
1217 * Valid algorithm values - one of OP_PCL_IPSEC_*
1219 * Return: size of descriptor written in words or negative number on error
1222 cnstr_shdsc_ipsec_new_decap(uint32_t *descbuf, bool ps,
1224 struct ipsec_decap_pdb *pdb,
1225 struct alginfo *cipherdata,
1226 struct alginfo *authdata)
1229 struct program *p = &prg;
1236 if (rta_sec_era < RTA_SEC_ERA_8) {
1237 pr_err("IPsec new mode decap: available only for Era %d or above\n",
1238 USER_SEC_ERA(RTA_SEC_ERA_8));
1242 PROGRAM_CNTXT_INIT(p, descbuf, 0);
1244 PROGRAM_SET_BSWAP(p);
1246 PROGRAM_SET_36BIT_ADDR(p);
1247 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
1248 __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
1250 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1251 if (authdata->keylen)
1252 __gen_auth_key(p, authdata);
1253 if (cipherdata->keylen)
1254 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1255 cipherdata->keylen, INLINE_KEY(cipherdata));
1256 SET_LABEL(p, keyjmp);
1257 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
1259 (uint16_t)(cipherdata->algtype | authdata->algtype));
1260 PATCH_JUMP(p, pkeyjmp, keyjmp);
1261 PATCH_HDR(p, phdr, hdr);
1262 return PROGRAM_FINALIZE(p);
1266 * IPSEC_AUTH_VAR_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1267 * for the case of variable-length authentication
1269 * Note: Only for SoCs with SEC_ERA >= 3.
1271 * Accounts only for the "base" commands and is intended to be used by upper
1272 * layers to determine whether keys can be inlined or not. To be used as first
1273 * parameter of rta_inline_query().
1275 #define IPSEC_AUTH_VAR_BASE_DESC_LEN (27 * CAAM_CMD_SZ)
1278 * IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor
1279 * length for variable-length authentication only
1281 * Note: Only for SoCs with SEC_ERA >= 3.
1283 * Accounts only for the "base" commands and is intended to be used by upper
1284 * layers to determine whether key can be inlined or not. To be used as first
1285 * parameter of rta_inline_query().
1287 #define IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN \
1288 (IPSEC_AUTH_VAR_BASE_DESC_LEN + CAAM_CMD_SZ)
1291 * IPSEC_AUTH_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1293 * Accounts only for the "base" commands and is intended to be used by upper
1294 * layers to determine whether key can be inlined or not. To be used as first
1295 * parameter of rta_inline_query().
1297 #define IPSEC_AUTH_BASE_DESC_LEN (19 * CAAM_CMD_SZ)
1300 * IPSEC_AUTH_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor length
1302 * Accounts only for the "base" commands and is intended to be used by upper
1303 * layers to determine whether key can be inlined or not. To be used as first
1304 * parameter of rta_inline_query().
1306 #define IPSEC_AUTH_AES_DEC_BASE_DESC_LEN (IPSEC_AUTH_BASE_DESC_LEN + \
1310 * cnstr_shdsc_authenc - authenc-like descriptor
1311 * @descbuf: pointer to buffer used for descriptor construction
1312 * @ps: if 36/40bit addressing is desired, this parameter must be true
1313 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
1314 * @cipherdata: pointer to block cipher transform definitions.
1315 * Valid algorithm values one of OP_ALG_ALGSEL_* {DES, 3DES, AES}
1317 * AES: OP_ALG_AAI_* {CBC, CTR}
1318 * DES, 3DES: OP_ALG_AAI_CBC
1319 * @authdata: pointer to authentication transform definitions.
1320 * Valid algorithm values - one of OP_ALG_ALGSEL_* {MD5, SHA1,
1321 * SHA224, SHA256, SHA384, SHA512}
1322 * Note: The key for authentication is supposed to be given as plain text.
1323 * Note: There's no support for keys longer than the block size of the
1324 * underlying hash function, according to the selected algorithm.
1326 * @ivlen: length of the IV to be read from the input frame, before any data
1328 * @auth_only_len: length of the data to be authenticated-only (commonly IP
1329 * header, IV, Sequence number and SPI)
1330 * Note: Extended Sequence Number processing is NOT supported
1332 * @trunc_len: the length of the ICV to be written to the output frame. If 0,
1333 * then the corresponding length of the digest, according to the
1334 * selected algorithm shall be used.
1335 * @dir: Protocol direction, encapsulation or decapsulation (DIR_ENC/DIR_DEC)
1337 * Note: Here's how the input frame needs to be formatted so that the processing
1338 * will be done correctly:
1339 * For encapsulation:
1341 * +----+----------------+---------------------------------------------+
1342 * | IV | Auth-only data | Padded data to be authenticated & Encrypted |
1343 * +----+----------------+---------------------------------------------+
1345 * +--------------------------------------+
1346 * | Authenticated & Encrypted data | ICV |
1347 * +--------------------------------+-----+
1349 * For decapsulation:
1351 * +----+----------------+--------------------------------+-----+
1352 * | IV | Auth-only data | Authenticated & Encrypted data | ICV |
1353 * +----+----------------+--------------------------------+-----+
1355 * +----+--------------------------+
1356 * | Decrypted & authenticated data |
1357 * +----+--------------------------+
1359 * Note: This descriptor can use per-packet commands, encoded as below in the
1362 * +------+---------------------+
1363 * | 0x80 | 0x00| auth_only_len |
1364 * +------+---------------------+
1366 * This mechanism is available only for SoCs having SEC ERA >= 3. In other
1367 * words, this will not work for P4080TO2
1369 * Note: The descriptor does not add any kind of padding to the input data,
1370 * so the upper layer needs to ensure that the data is padded properly,
1371 * according to the selected cipher. Failure to do so will result in
1372 * the descriptor failing with a data-size error.
1374 * Return: size of descriptor written in words or negative number on error
1377 cnstr_shdsc_authenc(uint32_t *descbuf, bool ps, bool swap,
1378 struct alginfo *cipherdata,
1379 struct alginfo *authdata,
1380 uint16_t ivlen, uint16_t auth_only_len,
1381 uint8_t trunc_len, uint8_t dir)
1384 struct program *p = &prg;
1385 const bool need_dk = (dir == DIR_DEC) &&
1386 (cipherdata->algtype == OP_ALG_ALGSEL_AES) &&
1387 (cipherdata->algmode == OP_ALG_AAI_CBC);
1389 LABEL(skip_patch_len);
1392 LABEL(aonly_len_offset);
1393 REFERENCE(pskip_patch_len);
1395 REFERENCE(pskipkeys);
1396 REFERENCE(read_len);
1397 REFERENCE(write_len);
1399 PROGRAM_CNTXT_INIT(p, descbuf, 0);
1402 PROGRAM_SET_BSWAP(p);
1404 PROGRAM_SET_36BIT_ADDR(p);
1407 * Since we currently assume that key length is equal to hash digest
1408 * size, it's ok to truncate keylen value.
1410 trunc_len = trunc_len && (trunc_len < authdata->keylen) ?
1411 trunc_len : (uint8_t)authdata->keylen;
1413 SHR_HDR(p, SHR_SERIAL, 1, SC);
1416 * M0 will contain the value provided by the user when creating
1417 * the shared descriptor. If the user provided an override in
1418 * DPOVRD, then M0 will contain that value
1420 MATHB(p, MATH0, ADD, auth_only_len, MATH0, 4, IMMED2);
1422 if (rta_sec_era >= RTA_SEC_ERA_3) {
1424 * Check if the user wants to override the auth-only len
1426 MATHB(p, DPOVRD, ADD, 0x80000000, MATH2, 4, IMMED2);
1429 * No need to patch the length of the auth-only data read if
1430 * the user did not override it
1432 pskip_patch_len = JUMP(p, skip_patch_len, LOCAL_JUMP, ALL_TRUE,
1435 /* Get auth-only len in M0 */
1436 MATHB(p, MATH2, AND, 0xFFFF, MATH0, 4, IMMED2);
1439 * Since M0 is used in calculations, don't mangle it, copy
1440 * its content to M1 and use this for patching.
1442 MATHB(p, MATH0, ADD, MATH1, MATH1, 4, 0);
1444 read_len = MOVE(p, DESCBUF, 0, MATH1, 0, 6, WAITCOMP | IMMED);
1445 write_len = MOVE(p, MATH1, 0, DESCBUF, 0, 8, WAITCOMP | IMMED);
1447 SET_LABEL(p, skip_patch_len);
1450 * MATH0 contains the value in DPOVRD w/o the MSB, or the initial
1451 * value, as provided by the user at descriptor creation time
1454 MATHB(p, MATH0, ADD, ivlen, MATH0, 4, IMMED2);
1456 MATHB(p, MATH0, ADD, ivlen + trunc_len, MATH0, 4, IMMED2);
1458 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1460 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1461 INLINE_KEY(authdata));
1464 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1465 cipherdata->keylen, INLINE_KEY(cipherdata));
1468 ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC,
1469 OP_ALG_AS_INITFINAL,
1470 dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1474 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode,
1475 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1476 pskipkeys = JUMP(p, skipkeys, LOCAL_JUMP, ALL_TRUE, 0);
1478 SET_LABEL(p, keyjmp);
1480 ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
1481 OP_ALG_AS_INITFINAL,
1482 dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1486 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode |
1487 OP_ALG_AAI_DK, OP_ALG_AS_INITFINAL,
1488 ICV_CHECK_DISABLE, dir);
1489 SET_LABEL(p, skipkeys);
1491 SET_LABEL(p, skipkeys);
1492 ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
1493 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1497 * Prepare the length of the data to be both encrypted/decrypted
1498 * and authenticated/checked
1500 MATHB(p, SEQINSZ, SUB, MATH0, VSEQINSZ, 4, 0);
1502 MATHB(p, VSEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
1504 /* Prepare for writing the output frame */
1505 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1507 SET_LABEL(p, aonly_len_offset);
1510 if (cipherdata->algmode == OP_ALG_AAI_CTR)
1511 SEQLOAD(p, CONTEXT1, 16, ivlen, 0);
1513 SEQLOAD(p, CONTEXT1, 0, ivlen, 0);
1516 * Read data needed only for authentication. This is overwritten above
1517 * if the user requested it.
1519 SEQFIFOLOAD(p, MSG2, auth_only_len, 0);
1521 if (dir == DIR_ENC) {
1523 * Read input plaintext, encrypt and authenticate & write to
1526 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
1528 /* Finally, write the ICV */
1529 SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
1532 * Read input ciphertext, decrypt and authenticate & write to
1535 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
1537 /* Read the ICV to check */
1538 SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
1541 PATCH_JUMP(p, pkeyjmp, keyjmp);
1542 PATCH_JUMP(p, pskipkeys, skipkeys);
1543 PATCH_JUMP(p, pskipkeys, skipkeys);
1545 if (rta_sec_era >= RTA_SEC_ERA_3) {
1546 PATCH_JUMP(p, pskip_patch_len, skip_patch_len);
1547 PATCH_MOVE(p, read_len, aonly_len_offset);
1548 PATCH_MOVE(p, write_len, aonly_len_offset);
1551 return PROGRAM_FINALIZE(p);
1554 #endif /* __DESC_IPSEC_H__ */