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