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