1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
3 * Copyright 2008-2016 Freescale Semiconductor Inc.
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 array nonce
260 * @ctr_initial: initial count constant
261 * @iv: initialization vector
263 struct ipsec_encap_ctr {
264 uint8_t ctr_nonce[4];
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, pdb->ctr.ctr_nonce,
350 sizeof(pdb->ctr.ctr_nonce));
351 __rta_out32(program, pdb->ctr.ctr_initial);
352 __rta_out64(program, true, pdb->ctr.iv);
355 case OP_PCL_IPSEC_AES_CCM8:
356 case OP_PCL_IPSEC_AES_CCM12:
357 case OP_PCL_IPSEC_AES_CCM16:
358 rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
359 __rta_out32(program, pdb->ccm.ccm_opt);
360 __rta_out64(program, true, pdb->ccm.iv);
363 case OP_PCL_IPSEC_AES_GCM8:
364 case OP_PCL_IPSEC_AES_GCM12:
365 case OP_PCL_IPSEC_AES_GCM16:
366 case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
367 rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
368 __rta_out32(program, pdb->gcm.rsvd);
369 __rta_out64(program, true, pdb->gcm.iv);
373 __rta_out32(program, pdb->spi);
374 __rta_out32(program, pdb->ip_hdr_len);
380 * struct ipsec_decap_cbc - PDB part for IPsec CBC decapsulation
381 * @rsvd: reserved, do not use
383 struct ipsec_decap_cbc {
388 * struct ipsec_decap_ctr - PDB part for IPsec CTR decapsulation
389 * @ctr_nonce: 4-byte array nonce
390 * @ctr_initial: initial count constant
392 struct ipsec_decap_ctr {
393 uint8_t ctr_nonce[4];
394 uint32_t ctr_initial;
398 * struct ipsec_decap_ccm - PDB part for IPsec CCM decapsulation
399 * @salt: 3-byte salt (lower 24 bits)
400 * @ccm_opt: CCM algorithm options - MSB-LSB description:
401 * b0_flags (8b) - CCM B0; use 0x5B for 8-byte ICV, 0x6B for 12-byte ICV,
402 * 0x7B for 16-byte ICV (cf. RFC4309, RFC3610)
403 * ctr_flags (8b) - counter flags; constant equal to 0x3
404 * ctr_initial (16b) - initial count constant
406 struct ipsec_decap_ccm {
412 * struct ipsec_decap_gcm - PDB part for IPsec GCN decapsulation
414 * @rsvd: reserved, do not use
416 struct ipsec_decap_gcm {
422 * struct ipsec_decap_pdb - PDB for IPsec decapsulation
423 * @options: MSB-LSB description (both for legacy and new modes)
424 * hmo (header manipulation options) - 4b
425 * IP header length - 12b
426 * next header offset (legacy) / AOIPHO (actual outer IP header offset) - 8b
427 * option flags (depend on selected algorithm) - 8b
428 * @seq_num_ext_hi: (optional) IPsec Extended Sequence Number (ESN)
429 * @seq_num: IPsec sequence number
430 * @anti_replay: Anti-replay window; size depends on ARS (option flags);
431 * format must be Big Endian, irrespective of platform
433 struct ipsec_decap_pdb {
436 struct ipsec_decap_cbc cbc;
437 struct ipsec_decap_ctr ctr;
438 struct ipsec_decap_ccm ccm;
439 struct ipsec_decap_gcm gcm;
441 uint32_t seq_num_ext_hi;
443 uint32_t anti_replay[4];
446 static inline unsigned int
447 __rta_copy_ipsec_decap_pdb(struct program *program,
448 struct ipsec_decap_pdb *pdb,
451 unsigned int start_pc = program->current_pc;
454 __rta_out32(program, pdb->options);
456 switch (algtype & OP_PCL_IPSEC_CIPHER_MASK) {
457 case OP_PCL_IPSEC_DES_IV64:
458 case OP_PCL_IPSEC_DES:
459 case OP_PCL_IPSEC_3DES:
460 case OP_PCL_IPSEC_AES_CBC:
461 case OP_PCL_IPSEC_NULL:
462 __rta_out32(program, pdb->cbc.rsvd[0]);
463 __rta_out32(program, pdb->cbc.rsvd[1]);
466 case OP_PCL_IPSEC_AES_CTR:
467 rta_copy_data(program, pdb->ctr.ctr_nonce,
468 sizeof(pdb->ctr.ctr_nonce));
469 __rta_out32(program, pdb->ctr.ctr_initial);
472 case OP_PCL_IPSEC_AES_CCM8:
473 case OP_PCL_IPSEC_AES_CCM12:
474 case OP_PCL_IPSEC_AES_CCM16:
475 rta_copy_data(program, pdb->ccm.salt, sizeof(pdb->ccm.salt));
476 __rta_out32(program, pdb->ccm.ccm_opt);
479 case OP_PCL_IPSEC_AES_GCM8:
480 case OP_PCL_IPSEC_AES_GCM12:
481 case OP_PCL_IPSEC_AES_GCM16:
482 case OP_PCL_IPSEC_AES_NULL_WITH_GMAC:
483 rta_copy_data(program, pdb->gcm.salt, sizeof(pdb->gcm.salt));
484 __rta_out32(program, pdb->gcm.rsvd);
488 __rta_out32(program, pdb->seq_num_ext_hi);
489 __rta_out32(program, pdb->seq_num);
491 switch (pdb->options & PDBOPTS_ESP_ARS_MASK) {
492 case PDBOPTS_ESP_ARS128:
495 case PDBOPTS_ESP_ARS64:
498 case PDBOPTS_ESP_ARS32:
501 case PDBOPTS_ESP_ARSNONE:
507 for (i = 0; i < ars; i++)
508 __rta_out_be32(program, pdb->anti_replay[i]);
514 * enum ipsec_icv_size - Type selectors for icv size in IPsec protocol
515 * @IPSEC_ICV_MD5_SIZE: full-length MD5 ICV
516 * @IPSEC_ICV_MD5_TRUNC_SIZE: truncated MD5 ICV
518 enum ipsec_icv_size {
519 IPSEC_ICV_MD5_SIZE = 16,
520 IPSEC_ICV_MD5_TRUNC_SIZE = 12
524 * IPSec ESP Datapath Protocol Override Register (DPOVRD)
527 #define IPSEC_DECO_DPOVRD_USE 0x80
529 struct ipsec_deco_dpovrd {
534 uint8_t next_header; /* next header if encap */
535 uint8_t rsvd; /* reserved if decap */
539 struct ipsec_new_encap_deco_dpovrd {
540 #define IPSEC_NEW_ENCAP_DECO_DPOVRD_USE 0x8000
541 uint16_t ovrd_ip_hdr_len; /* OVRD + outer IP header material
544 #define IPSEC_NEW_ENCAP_OIMIF 0x80
545 uint8_t oimif_aoipho; /* OIMIF + actual outer IP header
551 struct ipsec_new_decap_deco_dpovrd {
553 uint8_t aoipho_hi; /* upper nibble of actual outer IP
556 uint16_t aoipho_lo_ip_hdr_len; /* lower nibble of actual outer IP
557 * header + outer IP header material
562 __gen_auth_key(struct program *program, struct alginfo *authdata)
566 switch (authdata->algtype & OP_PCL_IPSEC_AUTH_MASK) {
567 case OP_PCL_IPSEC_HMAC_MD5_96:
568 case OP_PCL_IPSEC_HMAC_MD5_128:
569 dkp_protid = OP_PCLID_DKP_MD5;
571 case OP_PCL_IPSEC_HMAC_SHA1_96:
572 case OP_PCL_IPSEC_HMAC_SHA1_160:
573 dkp_protid = OP_PCLID_DKP_SHA1;
575 case OP_PCL_IPSEC_HMAC_SHA2_256_128:
576 dkp_protid = OP_PCLID_DKP_SHA256;
578 case OP_PCL_IPSEC_HMAC_SHA2_384_192:
579 dkp_protid = OP_PCLID_DKP_SHA384;
581 case OP_PCL_IPSEC_HMAC_SHA2_512_256:
582 dkp_protid = OP_PCLID_DKP_SHA512;
585 KEY(program, KEY2, authdata->key_enc_flags, authdata->key,
586 authdata->keylen, INLINE_KEY(authdata));
590 if (authdata->key_type == RTA_DATA_PTR)
591 DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_PTR,
592 OP_PCL_DKP_DST_PTR, (uint16_t)authdata->keylen,
593 authdata->key, authdata->key_type);
595 DKP_PROTOCOL(program, dkp_protid, OP_PCL_DKP_SRC_IMM,
596 OP_PCL_DKP_DST_IMM, (uint16_t)authdata->keylen,
597 authdata->key, authdata->key_type);
601 * cnstr_shdsc_ipsec_encap - IPSec ESP encapsulation protocol-level shared
603 * @descbuf: pointer to buffer used for descriptor construction
604 * @ps: if 36/40bit addressing is desired, this parameter must be true
605 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
606 * @pdb: pointer to the PDB to be used with this descriptor
607 * This structure will be copied inline to the descriptor under
608 * construction. No error checking will be made. Refer to the
609 * block guide for a details of the encapsulation PDB.
610 * @cipherdata: pointer to block cipher transform definitions
611 * Valid algorithm values - one of OP_PCL_IPSEC_*
612 * @authdata: pointer to authentication transform definitions
613 * If an authentication key is required by the protocol:
614 * -For SEC Eras 1-5, an MDHA split key must be provided;
615 * Note that the size of the split key itself must be specified.
616 * -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
617 * Key Protocol) will be used to compute MDHA on the fly in HW.
618 * Valid algorithm values - one of OP_PCL_IPSEC_*
620 * Return: size of descriptor written in words or negative number on error
623 cnstr_shdsc_ipsec_encap(uint32_t *descbuf, bool ps, bool swap,
624 struct ipsec_encap_pdb *pdb,
625 struct alginfo *cipherdata,
626 struct alginfo *authdata)
629 struct program *p = &prg;
636 PROGRAM_CNTXT_INIT(p, descbuf, 0);
638 PROGRAM_SET_BSWAP(p);
640 PROGRAM_SET_36BIT_ADDR(p);
641 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
642 __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
643 COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
645 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
646 if (authdata->keylen) {
647 if (rta_sec_era < RTA_SEC_ERA_6)
648 KEY(p, MDHA_SPLIT_KEY, authdata->key_enc_flags,
649 authdata->key, authdata->keylen,
650 INLINE_KEY(authdata));
652 __gen_auth_key(p, authdata);
654 if (cipherdata->keylen)
655 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
656 cipherdata->keylen, INLINE_KEY(cipherdata));
657 SET_LABEL(p, keyjmp);
658 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
660 (uint16_t)(cipherdata->algtype | authdata->algtype));
661 PATCH_JUMP(p, pkeyjmp, keyjmp);
662 PATCH_HDR(p, phdr, hdr);
663 return PROGRAM_FINALIZE(p);
667 * cnstr_shdsc_ipsec_decap - IPSec ESP decapsulation protocol-level shared
669 * @descbuf: pointer to buffer used for descriptor construction
670 * @ps: if 36/40bit addressing is desired, this parameter must be true
671 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
672 * @pdb: pointer to the PDB to be used with this descriptor
673 * This structure will be copied inline to the descriptor under
674 * construction. No error checking will be made. Refer to the
675 * block guide for details about the decapsulation PDB.
676 * @cipherdata: pointer to block cipher transform definitions.
677 * Valid algorithm values - one of OP_PCL_IPSEC_*
678 * @authdata: pointer to authentication transform definitions
679 * If an authentication key is required by the protocol:
680 * -For SEC Eras 1-5, an MDHA split key must be provided;
681 * Note that the size of the split key itself must be specified.
682 * -For SEC Eras 6+, a "normal" key must be provided; DKP (Derived
683 * Key Protocol) will be used to compute MDHA on the fly in HW.
684 * Valid algorithm values - one of OP_PCL_IPSEC_*
686 * Return: size of descriptor written in words or negative number on error
689 cnstr_shdsc_ipsec_decap(uint32_t *descbuf, bool ps, bool swap,
690 struct ipsec_decap_pdb *pdb,
691 struct alginfo *cipherdata,
692 struct alginfo *authdata)
695 struct program *p = &prg;
702 PROGRAM_CNTXT_INIT(p, descbuf, 0);
704 PROGRAM_SET_BSWAP(p);
706 PROGRAM_SET_36BIT_ADDR(p);
707 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
708 __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
710 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, BOTH|SHRD);
711 if (authdata->keylen) {
712 if (rta_sec_era < RTA_SEC_ERA_6)
713 KEY(p, MDHA_SPLIT_KEY, authdata->key_enc_flags,
714 authdata->key, authdata->keylen,
715 INLINE_KEY(authdata));
717 __gen_auth_key(p, authdata);
719 if (cipherdata->keylen)
720 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
721 cipherdata->keylen, INLINE_KEY(cipherdata));
722 SET_LABEL(p, keyjmp);
723 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
725 (uint16_t)(cipherdata->algtype | authdata->algtype));
726 PATCH_JUMP(p, pkeyjmp, keyjmp);
727 PATCH_HDR(p, phdr, hdr);
728 return PROGRAM_FINALIZE(p);
732 * cnstr_shdsc_ipsec_encap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
733 * AES-XCBC-MAC-96 ESP encapsulation shared descriptor.
734 * @descbuf: pointer to buffer used for descriptor construction
735 * @pdb: pointer to the PDB to be used with this descriptor
736 * This structure will be copied inline to the descriptor under
737 * construction. No error checking will be made. Refer to the
738 * block guide for a details of the encapsulation PDB.
739 * @cipherdata: pointer to block cipher transform definitions
740 * Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
741 * @authdata: pointer to authentication transform definitions
742 * Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
744 * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
745 * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
746 * Outer/Transport IP Header is present in the encapsulation output packet.
747 * The descriptor performs DES-CBC/3DES-CBC & HMAC-MD5-96 and then rereads
748 * the input packet to do the AES-XCBC-MAC-96 calculation and to overwrite
750 * The descriptor uses all the benefits of the built-in protocol by computing
751 * the IPsec ESP with a hardware supported algorithms combination
752 * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
753 * was chosen in order to speed up the computational time for this intermediate
755 * Warning: The user must allocate at least 32 bytes for the authentication key
756 * (in order to use it also with HMAC-MD5-96),even when using a shorter key
757 * for the AES-XCBC-MAC-96.
759 * Return: size of descriptor written in words or negative number on error
762 cnstr_shdsc_ipsec_encap_des_aes_xcbc(uint32_t *descbuf,
763 struct ipsec_encap_pdb *pdb,
764 struct alginfo *cipherdata,
765 struct alginfo *authdata)
768 struct program *p = &prg;
774 LABEL(swapped_seqin_fields);
775 LABEL(swapped_seqin_ptr);
778 REFERENCE(move_outlen);
779 REFERENCE(move_seqout_ptr);
780 REFERENCE(swapped_seqin_ptr_jump);
781 REFERENCE(write_swapped_seqin_ptr);
783 PROGRAM_CNTXT_INIT(p, descbuf, 0);
784 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
785 __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
786 COPY_DATA(p, pdb->ip_hdr, pdb->ip_hdr_len);
788 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
790 * Hard-coded KEY arguments. The descriptor uses all the benefits of
791 * the built-in protocol by computing the IPsec ESP with a hardware
792 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
793 * The HMAC-MD5 authentication algorithm was chosen with
794 * the keys options from below in order to speed up the computational
795 * time for this intermediate step.
796 * Warning: The user must allocate at least 32 bytes for
797 * the authentication key (in order to use it also with HMAC-MD5-96),
798 * even when using a shorter key for the AES-XCBC-MAC-96.
800 KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
801 SET_LABEL(p, keyjump);
802 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
803 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
805 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
806 cipherdata->keylen, INLINE_KEY(cipherdata));
807 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL, OP_PCLID_IPSEC,
808 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
809 /* Swap SEQINPTR to SEQOUTPTR. */
810 move_seqout_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
811 MATHB(p, MATH1, AND, ~(CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR), MATH1,
814 * TODO: RTA currently doesn't support creating a LOAD command
815 * with another command as IMM.
816 * To be changed when proper support is added in RTA.
818 LOAD(p, 0xa00000e5, MATH3, 4, 4, IMMED);
819 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
820 write_swapped_seqin_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
822 swapped_seqin_ptr_jump = JUMP(p, swapped_seqin_ptr, LOCAL_JUMP,
824 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
825 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
827 SEQOUTPTR(p, 0, 65535, RTO);
828 move_outlen = MOVE(p, DESCBUF, 0, MATH0, 4, 8, WAITCOMP | IMMED);
830 (uint64_t)(pdb->ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE),
831 VSEQINSZ, 4, IMMED2);
832 MATHB(p, MATH0, SUB, IPSEC_ICV_MD5_TRUNC_SIZE, VSEQOUTSZ, 4, IMMED2);
833 KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
835 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
836 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
837 SEQFIFOLOAD(p, SKIP, pdb->ip_hdr_len, 0);
838 SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1 | LAST1);
839 SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
840 SEQSTORE(p, CONTEXT1, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
842 * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
843 * To be changed when proper support is added in RTA.
845 /* Label the Shared Descriptor Pointer */
846 SET_LABEL(p, shd_ptr);
848 /* Label the Output Pointer */
849 SET_LABEL(p, outptr);
851 /* Label the first word after JD */
852 SET_LABEL(p, swapped_seqin_fields);
853 swapped_seqin_fields += 8;
854 /* Label the second word after JD */
855 SET_LABEL(p, swapped_seqin_ptr);
856 swapped_seqin_ptr += 9;
858 PATCH_HDR(p, phdr, hdr);
859 PATCH_JUMP(p, pkeyjump, keyjump);
860 PATCH_JUMP(p, swapped_seqin_ptr_jump, swapped_seqin_ptr);
861 PATCH_MOVE(p, move_outlen, outptr);
862 PATCH_MOVE(p, move_seqout_ptr, shd_ptr);
863 PATCH_MOVE(p, write_swapped_seqin_ptr, swapped_seqin_fields);
864 return PROGRAM_FINALIZE(p);
868 * cnstr_shdsc_ipsec_decap_des_aes_xcbc - IPSec DES-CBC/3DES-CBC and
869 * AES-XCBC-MAC-96 ESP decapsulation shared descriptor.
870 * @descbuf: pointer to buffer used for descriptor construction
871 * @pdb: pointer to the PDB to be used with this descriptor
872 * This structure will be copied inline to the descriptor under
873 * construction. No error checking will be made. Refer to the
874 * block guide for a details of the encapsulation PDB.
875 * @cipherdata: pointer to block cipher transform definitions
876 * Valid algorithm values - OP_PCL_IPSEC_DES, OP_PCL_IPSEC_3DES.
877 * @authdata: pointer to authentication transform definitions
878 * Valid algorithm value: OP_PCL_IPSEC_AES_XCBC_MAC_96.
880 * Supported only for platforms with 32-bit address pointers and SEC ERA 4 or
881 * higher. The tunnel/transport mode of the IPsec ESP is supported only if the
882 * Outer/Transport IP Header is present in the decapsulation input packet.
883 * The descriptor computes the AES-XCBC-MAC-96 to check if the received ICV
884 * is correct, rereads the input packet to compute the MD5 ICV, overwrites
885 * the XCBC ICV, and then sends the modified input packet to the
886 * DES-CBC/3DES-CBC & HMAC-MD5-96 IPsec.
887 * The descriptor uses all the benefits of the built-in protocol by computing
888 * the IPsec ESP with a hardware supported algorithms combination
889 * (DES-CBC/3DES-CBC & HMAC-MD5-96). The HMAC-MD5 authentication algorithm
890 * was chosen in order to speed up the computational time for this intermediate
892 * Warning: The user must allocate at least 32 bytes for the authentication key
893 * (in order to use it also with HMAC-MD5-96),even when using a shorter key
894 * for the AES-XCBC-MAC-96.
896 * Return: size of descriptor written in words or negative number on error
899 cnstr_shdsc_ipsec_decap_des_aes_xcbc(uint32_t *descbuf,
900 struct ipsec_decap_pdb *pdb,
901 struct alginfo *cipherdata,
902 struct alginfo *authdata)
905 struct program *p = &prg;
906 uint32_t ip_hdr_len = (pdb->options & PDBHDRLEN_MASK) >>
907 PDBHDRLEN_ESP_DECAP_SHIFT;
915 LABEL(swapped_seqout_fields);
916 LABEL(swapped_seqout_ptr);
917 REFERENCE(seqout_ptr_jump);
920 REFERENCE(move_jump);
921 REFERENCE(move_jump_back);
922 REFERENCE(move_seqin_ptr);
923 REFERENCE(swapped_seqout_ptr_jump);
924 REFERENCE(write_swapped_seqout_ptr);
926 PROGRAM_CNTXT_INIT(p, descbuf, 0);
927 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
928 __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
930 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF);
932 * Hard-coded KEY arguments. The descriptor uses all the benefits of
933 * the built-in protocol by computing the IPsec ESP with a hardware
934 * supported algorithms combination (DES-CBC/3DES-CBC & HMAC-MD5-96).
935 * The HMAC-MD5 authentication algorithm was chosen with
936 * the keys options from bellow in order to speed up the computational
937 * time for this intermediate step.
938 * Warning: The user must allocate at least 32 bytes for
939 * the authentication key (in order to use it also with HMAC-MD5-96),
940 * even when using a shorter key for the AES-XCBC-MAC-96.
942 KEY(p, MDHA_SPLIT_KEY, 0, authdata->key, 32, INLINE_KEY(authdata));
943 SET_LABEL(p, keyjump);
944 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
945 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_RESET_CLS1_CHA, CLRW, 0, 4,
947 KEY(p, KEY1, authdata->key_enc_flags, authdata->key, authdata->keylen,
948 INLINE_KEY(authdata));
949 MATHB(p, SEQINSZ, SUB,
950 (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), MATH0, 4,
952 MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
953 ALG_OPERATION(p, OP_ALG_ALGSEL_MD5, OP_ALG_AAI_HMAC_PRECOMP,
954 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
955 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_XCBC_MAC,
956 OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
957 SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
958 SEQFIFOLOAD(p, MSG1, 0, VLF | FLUSH1);
959 SEQFIFOLOAD(p, ICV1, IPSEC_ICV_MD5_TRUNC_SIZE, FLUSH1 | LAST1);
960 /* Swap SEQOUTPTR to SEQINPTR. */
961 move_seqin_ptr = MOVE(p, DESCBUF, 0, MATH1, 0, 16, WAITCOMP | IMMED);
962 MATHB(p, MATH1, OR, CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR, MATH1, 8,
965 * TODO: RTA currently doesn't support creating a LOAD command
966 * with another command as IMM.
967 * To be changed when proper support is added in RTA.
969 LOAD(p, 0xA00000e1, MATH3, 4, 4, IMMED);
970 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
971 write_swapped_seqout_ptr = MOVE(p, MATH1, 0, DESCBUF, 0, 20, WAITCOMP |
973 swapped_seqout_ptr_jump = JUMP(p, swapped_seqout_ptr, LOCAL_JUMP,
976 * TODO: To be changed when proper support is added in RTA (can't load
977 * a command that is also written by RTA).
978 * Change when proper RTA support is added.
980 SET_LABEL(p, jump_cmd);
982 SEQINPTR(p, 0, 65535, RTO);
983 MATHB(p, MATH0, SUB, ZERO, VSEQINSZ, 4, 0);
984 MATHB(p, MATH0, ADD, ip_hdr_len, VSEQOUTSZ, 4, IMMED2);
985 move_jump = MOVE(p, DESCBUF, 0, OFIFO, 0, 8, WAITCOMP | IMMED);
986 move_jump_back = MOVE(p, OFIFO, 0, DESCBUF, 0, 8, IMMED);
987 SEQFIFOLOAD(p, SKIP, ip_hdr_len, 0);
988 SEQFIFOLOAD(p, MSG2, 0, VLF | LAST2);
989 SEQFIFOSTORE(p, SKIP, 0, 0, VLF);
990 SEQSTORE(p, CONTEXT2, 0, IPSEC_ICV_MD5_TRUNC_SIZE, 0);
991 seqout_ptr_jump = JUMP(p, seqout_ptr, LOCAL_JUMP, ALL_TRUE, CALM);
993 LOAD(p, LDST_SRCDST_WORD_CLRW | CLRW_CLR_C1MODE | CLRW_CLR_C1DATAS |
994 CLRW_CLR_C1CTX | CLRW_CLR_C1KEY | CLRW_CLR_C2MODE |
995 CLRW_CLR_C2DATAS | CLRW_CLR_C2CTX | CLRW_RESET_CLS1_CHA, CLRW, 0,
997 SEQINPTR(p, 0, 65535, RTO);
999 (uint64_t)(ip_hdr_len + IPSEC_ICV_MD5_TRUNC_SIZE), SEQINSZ, 4,
1001 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1002 cipherdata->keylen, INLINE_KEY(cipherdata));
1003 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL, OP_PCLID_IPSEC,
1004 (uint16_t)(cipherdata->algtype | OP_PCL_IPSEC_HMAC_MD5_96));
1006 * TODO: RTA currently doesn't support adding labels in or after Job Descriptor.
1007 * To be changed when proper support is added in RTA.
1009 /* Label the SEQ OUT PTR */
1010 SET_LABEL(p, seqout_ptr);
1012 /* Label the Output Length */
1013 SET_LABEL(p, outlen);
1015 /* Label the SEQ IN PTR */
1016 SET_LABEL(p, seqin_ptr);
1018 /* Label the first word after JD */
1019 SET_LABEL(p, swapped_seqout_fields);
1020 swapped_seqout_fields += 8;
1021 /* Label the second word after JD */
1022 SET_LABEL(p, swapped_seqout_ptr);
1023 swapped_seqout_ptr += 9;
1025 PATCH_HDR(p, phdr, hdr);
1026 PATCH_JUMP(p, pkeyjump, keyjump);
1027 PATCH_JUMP(p, seqout_ptr_jump, seqout_ptr);
1028 PATCH_JUMP(p, swapped_seqout_ptr_jump, swapped_seqout_ptr);
1029 PATCH_MOVE(p, move_jump, jump_cmd);
1030 PATCH_MOVE(p, move_jump_back, seqin_ptr);
1031 PATCH_MOVE(p, move_seqin_ptr, outlen);
1032 PATCH_MOVE(p, write_swapped_seqout_ptr, swapped_seqout_fields);
1033 return PROGRAM_FINALIZE(p);
1037 * IPSEC_NEW_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor length
1039 * Accounts only for the "base" commands and is intended to be used by upper
1040 * layers to determine whether Outer IP Header and/or keys can be inlined or
1041 * not. To be used as first parameter of rta_inline_query().
1043 #define IPSEC_NEW_ENC_BASE_DESC_LEN (5 * CAAM_CMD_SZ + \
1044 sizeof(struct ipsec_encap_pdb))
1047 * IPSEC_NEW_NULL_ENC_BASE_DESC_LEN - IPsec new mode encap shared descriptor
1048 * length for the case of
1049 * NULL encryption / authentication
1051 * Accounts only for the "base" commands and is intended to be used by upper
1052 * layers to determine whether Outer IP Header and/or key can be inlined or
1053 * not. To be used as first parameter of rta_inline_query().
1055 #define IPSEC_NEW_NULL_ENC_BASE_DESC_LEN (4 * CAAM_CMD_SZ + \
1056 sizeof(struct ipsec_encap_pdb))
1059 * cnstr_shdsc_ipsec_new_encap - IPSec new mode ESP encapsulation
1060 * protocol-level shared descriptor.
1061 * @descbuf: pointer to buffer used for descriptor construction
1062 * @ps: if 36/40bit addressing is desired, this parameter must be true
1063 * @swap: must be true when core endianness doesn't match SEC endianness
1064 * @pdb: pointer to the PDB to be used with this descriptor
1065 * This structure will be copied inline to the descriptor under
1066 * construction. No error checking will be made. Refer to the
1067 * block guide for details about the encapsulation PDB.
1068 * @opt_ip_hdr: pointer to Optional IP Header
1069 * -if OIHI = PDBOPTS_ESP_OIHI_PDB_INL, opt_ip_hdr points to the buffer to
1070 * be inlined in the PDB. Number of bytes (buffer size) copied is provided
1071 * in pdb->ip_hdr_len.
1072 * -if OIHI = PDBOPTS_ESP_OIHI_PDB_REF, opt_ip_hdr points to the address of
1073 * the Optional IP Header. The address will be inlined in the PDB verbatim.
1074 * -for other values of OIHI options field, opt_ip_hdr is not used.
1075 * @cipherdata: pointer to block cipher transform definitions
1076 * Valid algorithm values - one of OP_PCL_IPSEC_*
1077 * @authdata: pointer to authentication transform definitions.
1078 * If an authentication key is required by the protocol, a "normal"
1079 * key must be provided; DKP (Derived Key Protocol) will be used to
1080 * compute MDHA on the fly in HW.
1081 * Valid algorithm values - one of OP_PCL_IPSEC_*
1083 * Return: size of descriptor written in words or negative number on error
1086 cnstr_shdsc_ipsec_new_encap(uint32_t *descbuf, bool ps,
1088 struct ipsec_encap_pdb *pdb,
1089 uint8_t *opt_ip_hdr,
1090 struct alginfo *cipherdata,
1091 struct alginfo *authdata)
1094 struct program *p = &prg;
1101 if (rta_sec_era < RTA_SEC_ERA_8) {
1102 pr_err("IPsec new mode encap: available only for Era %d or above\n",
1103 USER_SEC_ERA(RTA_SEC_ERA_8));
1107 PROGRAM_CNTXT_INIT(p, descbuf, 0);
1109 PROGRAM_SET_BSWAP(p);
1111 PROGRAM_SET_36BIT_ADDR(p);
1112 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
1114 __rta_copy_ipsec_encap_pdb(p, pdb, cipherdata->algtype);
1116 switch (pdb->options & PDBOPTS_ESP_OIHI_MASK) {
1117 case PDBOPTS_ESP_OIHI_PDB_INL:
1118 COPY_DATA(p, opt_ip_hdr, pdb->ip_hdr_len);
1120 case PDBOPTS_ESP_OIHI_PDB_REF:
1122 COPY_DATA(p, opt_ip_hdr, 8);
1124 COPY_DATA(p, opt_ip_hdr, 4);
1131 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1132 if (authdata->keylen)
1133 __gen_auth_key(p, authdata);
1134 if (cipherdata->keylen)
1135 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1136 cipherdata->keylen, INLINE_KEY(cipherdata));
1137 SET_LABEL(p, keyjmp);
1138 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
1140 (uint16_t)(cipherdata->algtype | authdata->algtype));
1141 PATCH_JUMP(p, pkeyjmp, keyjmp);
1142 PATCH_HDR(p, phdr, hdr);
1143 return PROGRAM_FINALIZE(p);
1147 * IPSEC_NEW_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor length
1149 * Accounts only for the "base" commands and is intended to be used by upper
1150 * layers to determine whether keys can be inlined or not. To be used as first
1151 * parameter of rta_inline_query().
1153 #define IPSEC_NEW_DEC_BASE_DESC_LEN (5 * CAAM_CMD_SZ + \
1154 sizeof(struct ipsec_decap_pdb))
1157 * IPSEC_NEW_NULL_DEC_BASE_DESC_LEN - IPsec new mode decap shared descriptor
1158 * length for the case of
1159 * NULL decryption / authentication
1161 * Accounts only for the "base" commands and is intended to be used by upper
1162 * layers to determine whether key can be inlined or not. To be used as first
1163 * parameter of rta_inline_query().
1165 #define IPSEC_NEW_NULL_DEC_BASE_DESC_LEN (4 * CAAM_CMD_SZ + \
1166 sizeof(struct ipsec_decap_pdb))
1169 * cnstr_shdsc_ipsec_new_decap - IPSec new mode ESP decapsulation protocol-level
1170 * shared descriptor.
1171 * @descbuf: pointer to buffer used for descriptor construction
1172 * @ps: if 36/40bit addressing is desired, this parameter must be true
1173 * @swap: must be true when core endianness doesn't match SEC endianness
1174 * @pdb: pointer to the PDB to be used with this descriptor
1175 * This structure will be copied inline to the descriptor under
1176 * construction. No error checking will be made. Refer to the
1177 * block guide for details about the decapsulation PDB.
1178 * @cipherdata: pointer to block cipher transform definitions
1179 * Valid algorithm values 0 one of OP_PCL_IPSEC_*
1180 * @authdata: pointer to authentication transform definitions.
1181 * If an authentication key is required by the protocol, a "normal"
1182 * key must be provided; DKP (Derived Key Protocol) will be used to
1183 * compute MDHA on the fly in HW.
1184 * Valid algorithm values - one of OP_PCL_IPSEC_*
1186 * Return: size of descriptor written in words or negative number on error
1189 cnstr_shdsc_ipsec_new_decap(uint32_t *descbuf, bool ps,
1191 struct ipsec_decap_pdb *pdb,
1192 struct alginfo *cipherdata,
1193 struct alginfo *authdata)
1196 struct program *p = &prg;
1203 if (rta_sec_era < RTA_SEC_ERA_8) {
1204 pr_err("IPsec new mode decap: available only for Era %d or above\n",
1205 USER_SEC_ERA(RTA_SEC_ERA_8));
1209 PROGRAM_CNTXT_INIT(p, descbuf, 0);
1211 PROGRAM_SET_BSWAP(p);
1213 PROGRAM_SET_36BIT_ADDR(p);
1214 phdr = SHR_HDR(p, SHR_SERIAL, hdr, 0);
1215 __rta_copy_ipsec_decap_pdb(p, pdb, cipherdata->algtype);
1217 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1218 if (authdata->keylen)
1219 __gen_auth_key(p, authdata);
1220 if (cipherdata->keylen)
1221 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1222 cipherdata->keylen, INLINE_KEY(cipherdata));
1223 SET_LABEL(p, keyjmp);
1224 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
1226 (uint16_t)(cipherdata->algtype | authdata->algtype));
1227 PATCH_JUMP(p, pkeyjmp, keyjmp);
1228 PATCH_HDR(p, phdr, hdr);
1229 return PROGRAM_FINALIZE(p);
1233 * IPSEC_AUTH_VAR_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1234 * for the case of variable-length authentication
1236 * Note: Only for SoCs with SEC_ERA >= 3.
1238 * Accounts only for the "base" commands and is intended to be used by upper
1239 * layers to determine whether keys can be inlined or not. To be used as first
1240 * parameter of rta_inline_query().
1242 #define IPSEC_AUTH_VAR_BASE_DESC_LEN (27 * CAAM_CMD_SZ)
1245 * IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor
1246 * length for variable-length authentication only
1248 * Note: Only for SoCs with SEC_ERA >= 3.
1250 * Accounts only for the "base" commands and is intended to be used by upper
1251 * layers to determine whether key can be inlined or not. To be used as first
1252 * parameter of rta_inline_query().
1254 #define IPSEC_AUTH_VAR_AES_DEC_BASE_DESC_LEN \
1255 (IPSEC_AUTH_VAR_BASE_DESC_LEN + CAAM_CMD_SZ)
1258 * IPSEC_AUTH_BASE_DESC_LEN - IPsec encap/decap shared descriptor length
1260 * Accounts only for the "base" commands and is intended to be used by upper
1261 * layers to determine whether key can be inlined or not. To be used as first
1262 * parameter of rta_inline_query().
1264 #define IPSEC_AUTH_BASE_DESC_LEN (19 * CAAM_CMD_SZ)
1267 * IPSEC_AUTH_AES_DEC_BASE_DESC_LEN - IPsec AES decap shared descriptor length
1269 * Accounts only for the "base" commands and is intended to be used by upper
1270 * layers to determine whether key can be inlined or not. To be used as first
1271 * parameter of rta_inline_query().
1273 #define IPSEC_AUTH_AES_DEC_BASE_DESC_LEN (IPSEC_AUTH_BASE_DESC_LEN + \
1277 * cnstr_shdsc_authenc - authenc-like descriptor
1278 * @descbuf: pointer to buffer used for descriptor construction
1279 * @ps: if 36/40bit addressing is desired, this parameter must be true
1280 * @swap: if true, perform descriptor byte swapping on a 4-byte boundary
1281 * @cipherdata: pointer to block cipher transform definitions.
1282 * Valid algorithm values one of OP_ALG_ALGSEL_* {DES, 3DES, AES}
1284 * AES: OP_ALG_AAI_* {CBC, CTR}
1285 * DES, 3DES: OP_ALG_AAI_CBC
1286 * @authdata: pointer to authentication transform definitions.
1287 * Valid algorithm values - one of OP_ALG_ALGSEL_* {MD5, SHA1,
1288 * SHA224, SHA256, SHA384, SHA512}
1289 * Note: The key for authentication is supposed to be given as plain text.
1290 * Note: There's no support for keys longer than the block size of the
1291 * underlying hash function, according to the selected algorithm.
1293 * @ivlen: length of the IV to be read from the input frame, before any data
1295 * @auth_only_len: length of the data to be authenticated-only (commonly IP
1296 * header, IV, Sequence number and SPI)
1297 * Note: Extended Sequence Number processing is NOT supported
1299 * @trunc_len: the length of the ICV to be written to the output frame. If 0,
1300 * then the corresponding length of the digest, according to the
1301 * selected algorithm shall be used.
1302 * @dir: Protocol direction, encapsulation or decapsulation (DIR_ENC/DIR_DEC)
1304 * Note: Here's how the input frame needs to be formatted so that the processing
1305 * will be done correctly:
1306 * For encapsulation:
1308 * +----+----------------+---------------------------------------------+
1309 * | IV | Auth-only data | Padded data to be authenticated & Encrypted |
1310 * +----+----------------+---------------------------------------------+
1312 * +--------------------------------------+
1313 * | Authenticated & Encrypted data | ICV |
1314 * +--------------------------------+-----+
1316 * For decapsulation:
1318 * +----+----------------+--------------------------------+-----+
1319 * | IV | Auth-only data | Authenticated & Encrypted data | ICV |
1320 * +----+----------------+--------------------------------+-----+
1322 * +----+--------------------------+
1323 * | Decrypted & authenticated data |
1324 * +----+--------------------------+
1326 * Note: This descriptor can use per-packet commands, encoded as below in the
1329 * +------+---------------------+
1330 * | 0x80 | 0x00| auth_only_len |
1331 * +------+---------------------+
1333 * This mechanism is available only for SoCs having SEC ERA >= 3. In other
1334 * words, this will not work for P4080TO2
1336 * Note: The descriptor does not add any kind of padding to the input data,
1337 * so the upper layer needs to ensure that the data is padded properly,
1338 * according to the selected cipher. Failure to do so will result in
1339 * the descriptor failing with a data-size error.
1341 * Return: size of descriptor written in words or negative number on error
1344 cnstr_shdsc_authenc(uint32_t *descbuf, bool ps, bool swap,
1345 struct alginfo *cipherdata,
1346 struct alginfo *authdata,
1347 uint16_t ivlen, uint16_t auth_only_len,
1348 uint8_t trunc_len, uint8_t dir)
1351 struct program *p = &prg;
1352 const bool need_dk = (dir == DIR_DEC) &&
1353 (cipherdata->algtype == OP_ALG_ALGSEL_AES) &&
1354 (cipherdata->algmode == OP_ALG_AAI_CBC);
1356 LABEL(skip_patch_len);
1359 LABEL(aonly_len_offset);
1360 REFERENCE(pskip_patch_len);
1362 REFERENCE(pskipkeys);
1363 REFERENCE(read_len);
1364 REFERENCE(write_len);
1366 PROGRAM_CNTXT_INIT(p, descbuf, 0);
1369 PROGRAM_SET_BSWAP(p);
1371 PROGRAM_SET_36BIT_ADDR(p);
1374 * Since we currently assume that key length is equal to hash digest
1375 * size, it's ok to truncate keylen value.
1377 trunc_len = trunc_len && (trunc_len < authdata->keylen) ?
1378 trunc_len : (uint8_t)authdata->keylen;
1380 SHR_HDR(p, SHR_SERIAL, 1, SC);
1383 * M0 will contain the value provided by the user when creating
1384 * the shared descriptor. If the user provided an override in
1385 * DPOVRD, then M0 will contain that value
1387 MATHB(p, MATH0, ADD, auth_only_len, MATH0, 4, IMMED2);
1389 if (rta_sec_era >= RTA_SEC_ERA_3) {
1391 * Check if the user wants to override the auth-only len
1393 MATHB(p, DPOVRD, ADD, 0x80000000, MATH2, 4, IMMED2);
1396 * No need to patch the length of the auth-only data read if
1397 * the user did not override it
1399 pskip_patch_len = JUMP(p, skip_patch_len, LOCAL_JUMP, ALL_TRUE,
1402 /* Get auth-only len in M0 */
1403 MATHB(p, MATH2, AND, 0xFFFF, MATH0, 4, IMMED2);
1406 * Since M0 is used in calculations, don't mangle it, copy
1407 * its content to M1 and use this for patching.
1409 MATHB(p, MATH0, ADD, MATH1, MATH1, 4, 0);
1411 read_len = MOVE(p, DESCBUF, 0, MATH1, 0, 6, WAITCOMP | IMMED);
1412 write_len = MOVE(p, MATH1, 0, DESCBUF, 0, 8, WAITCOMP | IMMED);
1414 SET_LABEL(p, skip_patch_len);
1417 * MATH0 contains the value in DPOVRD w/o the MSB, or the initial
1418 * value, as provided by the user at descriptor creation time
1421 MATHB(p, MATH0, ADD, ivlen, MATH0, 4, IMMED2);
1423 MATHB(p, MATH0, ADD, ivlen + trunc_len, MATH0, 4, IMMED2);
1425 pkeyjmp = JUMP(p, keyjmp, LOCAL_JUMP, ALL_TRUE, SHRD);
1427 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1428 INLINE_KEY(authdata));
1431 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1432 cipherdata->keylen, INLINE_KEY(cipherdata));
1435 ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC,
1436 OP_ALG_AS_INITFINAL,
1437 dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1441 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode,
1442 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1443 pskipkeys = JUMP(p, skipkeys, LOCAL_JUMP, ALL_TRUE, 0);
1445 SET_LABEL(p, keyjmp);
1447 ALG_OPERATION(p, authdata->algtype, OP_ALG_AAI_HMAC_PRECOMP,
1448 OP_ALG_AS_INITFINAL,
1449 dir == DIR_ENC ? ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1453 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, cipherdata->algmode |
1454 OP_ALG_AAI_DK, OP_ALG_AS_INITFINAL,
1455 ICV_CHECK_DISABLE, dir);
1456 SET_LABEL(p, skipkeys);
1458 SET_LABEL(p, skipkeys);
1459 ALG_OPERATION(p, cipherdata->algtype, cipherdata->algmode,
1460 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, dir);
1464 * Prepare the length of the data to be both encrypted/decrypted
1465 * and authenticated/checked
1467 MATHB(p, SEQINSZ, SUB, MATH0, VSEQINSZ, 4, 0);
1469 MATHB(p, VSEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
1471 /* Prepare for writing the output frame */
1472 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1474 SET_LABEL(p, aonly_len_offset);
1477 if (cipherdata->algmode == OP_ALG_AAI_CTR)
1478 SEQLOAD(p, CONTEXT1, 16, ivlen, 0);
1480 SEQLOAD(p, CONTEXT1, 0, ivlen, 0);
1483 * Read data needed only for authentication. This is overwritten above
1484 * if the user requested it.
1486 SEQFIFOLOAD(p, MSG2, auth_only_len, 0);
1488 if (dir == DIR_ENC) {
1490 * Read input plaintext, encrypt and authenticate & write to
1493 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
1495 /* Finally, write the ICV */
1496 SEQSTORE(p, CONTEXT2, 0, trunc_len, 0);
1499 * Read input ciphertext, decrypt and authenticate & write to
1502 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
1504 /* Read the ICV to check */
1505 SEQFIFOLOAD(p, ICV2, trunc_len, LAST2);
1508 PATCH_JUMP(p, pkeyjmp, keyjmp);
1509 PATCH_JUMP(p, pskipkeys, skipkeys);
1510 PATCH_JUMP(p, pskipkeys, skipkeys);
1512 if (rta_sec_era >= RTA_SEC_ERA_3) {
1513 PATCH_JUMP(p, pskip_patch_len, skip_patch_len);
1514 PATCH_MOVE(p, read_len, aonly_len_offset);
1515 PATCH_MOVE(p, write_len, aonly_len_offset);
1518 return PROGRAM_FINALIZE(p);
1521 #endif /* __DESC_IPSEC_H__ */