1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2020 NXP 3 */ 4 5 #ifndef __DESC_SDAP_H__ 6 #define __DESC_SDAP_H__ 7 8 #include "rta.h" 9 #include "common.h" 10 #include "pdcp.h" 11 12 /* The file defines all the functions to do PDCP without protocol support in 13 * SEC 14 */ 15 16 /* Enable SDAP support */ 17 #define SDAP_SUPPORT 18 #ifdef SDAP_SUPPORT 19 #define SDAP_BYTE_SIZE 1 20 #define SDAP_BITS_SIZE (SDAP_BYTE_SIZE * 8) 21 #endif 22 23 static inline void key_loading_opti(struct program *p, 24 struct alginfo *cipherdata, 25 struct alginfo *authdata) 26 { 27 LABEL(lbl_skip_key_loading_jump); 28 REFERENCE(ref_skip_key_loading_jump); 29 30 /* Optimisation to bypass key loading (and decryption of the keys): 31 * Jump command testing: 32 * - SHRD: Descriptor is shared 33 * - SELF: The shared descriptor is in the same DECO 34 * - BOTH: The Class 1 and 2 CHA have finished 35 * -> If this is true, we jump and skip loading of the keys as they are 36 * already loaded 37 */ 38 ref_skip_key_loading_jump = 39 JUMP(p, lbl_skip_key_loading_jump, LOCAL_JUMP, ALL_TRUE, 40 SHRD | SELF | BOTH); 41 42 /* Load the keys */ 43 if (cipherdata) { 44 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key, 45 cipherdata->keylen, INLINE_KEY(cipherdata)); 46 } 47 48 if (authdata) { 49 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, 50 authdata->keylen, INLINE_KEY(authdata)); 51 } 52 53 /* Save the place where we want the jump to go */ 54 SET_LABEL(p, lbl_skip_key_loading_jump); 55 /* Update the jump command with the position where to jump */ 56 PATCH_JUMP(p, ref_skip_key_loading_jump, lbl_skip_key_loading_jump); 57 } 58 59 static inline int pdcp_sdap_get_sn_parameters(enum pdcp_sn_size sn_size, 60 bool swap, uint32_t *offset, 61 uint32_t *length, 62 uint32_t *sn_mask) 63 { 64 switch (sn_size) { 65 case PDCP_SN_SIZE_5: 66 *offset = 7; 67 *length = 1; 68 *sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK : 69 PDCP_C_PLANE_SN_MASK_BE; 70 break; 71 case PDCP_SN_SIZE_7: 72 *offset = 7; 73 *length = 1; 74 *sn_mask = (swap == false) ? PDCP_7BIT_SN_MASK : 75 PDCP_7BIT_SN_MASK_BE; 76 break; 77 case PDCP_SN_SIZE_12: 78 *offset = 6; 79 *length = 2; 80 *sn_mask = (swap == false) ? PDCP_12BIT_SN_MASK : 81 PDCP_12BIT_SN_MASK_BE; 82 break; 83 case PDCP_SN_SIZE_15: 84 *offset = 6; 85 *length = 2; 86 *sn_mask = (swap == false) ? PDCP_U_PLANE_15BIT_SN_MASK : 87 PDCP_U_PLANE_15BIT_SN_MASK_BE; 88 break; 89 case PDCP_SN_SIZE_18: 90 *offset = 5; 91 *length = 3; 92 *sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK : 93 PDCP_U_PLANE_18BIT_SN_MASK_BE; 94 break; 95 default: 96 pr_err("Invalid sn_size for %s\n", __func__); 97 return -ENOTSUP; 98 } 99 100 #ifdef SDAP_SUPPORT 101 *length += SDAP_BYTE_SIZE; 102 *offset -= SDAP_BYTE_SIZE; 103 #endif 104 105 return 0; 106 } 107 108 static inline int pdcp_sdap_insert_no_int_op(struct program *p, 109 bool swap __maybe_unused, 110 struct alginfo *cipherdata, 111 unsigned int dir, 112 enum pdcp_sn_size sn_size) 113 { 114 int op; 115 uint32_t sn_mask = 0; 116 uint32_t length = 0; 117 uint32_t offset = 0; 118 119 if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length, 120 &sn_mask)) 121 return -ENOTSUP; 122 123 /* Load key */ 124 key_loading_opti(p, cipherdata, NULL); 125 126 SEQLOAD(p, MATH0, offset, length, 0); 127 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM); 128 #ifdef SDAP_SUPPORT 129 rta_mathi(p, MATH0, 130 ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT), 131 SDAP_BITS_SIZE, MATH1, 8, 0); 132 MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2); 133 #else 134 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2); 135 #endif 136 137 SEQSTORE(p, MATH0, offset, length, 0); 138 139 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0); 140 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED); 141 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0); 142 143 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0); 144 MATHB(p, SEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0); 145 146 SEQFIFOSTORE(p, MSG, 0, 0, VLF); 147 148 op = dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC; 149 switch (cipherdata->algtype) { 150 case PDCP_CIPHER_TYPE_SNOW: 151 /* Copy the IV */ 152 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED); 153 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8, 154 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op); 155 break; 156 157 case PDCP_CIPHER_TYPE_AES: 158 /* The first 64 bits are 0 */ 159 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, WAITCOMP | IMMED); 160 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CTR, 161 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op); 162 break; 163 164 case PDCP_CIPHER_TYPE_ZUC: 165 if (rta_sec_era < RTA_SEC_ERA_5) { 166 pr_err("Invalid era for selected algorithm\n"); 167 return -ENOTSUP; 168 } 169 /* The LSB and MSB is the same for ZUC context */ 170 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED); 171 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED); 172 173 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE, OP_ALG_AAI_F8, 174 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op); 175 break; 176 177 default: 178 pr_err("%s: Invalid encrypt algorithm selected: %d\n", 179 "pdcp_sdap_insert_15bit_op", cipherdata->algtype); 180 return -EINVAL; 181 } 182 183 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1); 184 185 return 0; 186 } 187 188 static inline int 189 pdcp_sdap_insert_enc_only_op(struct program *p, bool swap __maybe_unused, 190 struct alginfo *cipherdata, 191 struct alginfo *authdata __maybe_unused, 192 unsigned int dir, enum pdcp_sn_size sn_size, 193 unsigned char era_2_sw_hfn_ovrd __maybe_unused) 194 { 195 uint32_t offset = 0, length = 0, sn_mask = 0; 196 197 if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length, 198 &sn_mask)) 199 return -ENOTSUP; 200 201 /* Load key */ 202 key_loading_opti(p, cipherdata, NULL); 203 204 /* Load header */ 205 SEQLOAD(p, MATH0, offset, length, 0); 206 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM); 207 208 #ifdef SDAP_SUPPORT 209 rta_mathi(p, MATH0, 210 ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT), 211 SDAP_BITS_SIZE, MATH1, 8, 0); 212 MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2); 213 #else 214 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2); 215 #endif 216 217 /* Word (32 bit) swap */ 218 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0); 219 /* Load words from PDB: word 02 (HFN) + word 03 (bearer_dir)*/ 220 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED); 221 /* Create basic IV */ 222 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0); 223 224 /* Write header */ 225 SEQSTORE(p, MATH0, offset, length, 0); 226 227 if (rta_sec_era > RTA_SEC_ERA_2) { 228 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0); 229 } else { 230 MATHB(p, SEQINSZ, SUB, ONE, MATH1, 4, 0); 231 MATHB(p, MATH1, ADD, ONE, VSEQINSZ, 4, 0); 232 } 233 234 if (dir == OP_TYPE_ENCAP_PROTOCOL) 235 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2); 236 else 237 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2); 238 239 switch (cipherdata->algtype) { 240 case PDCP_CIPHER_TYPE_SNOW: 241 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED); 242 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT); 243 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8, 244 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, 245 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : 246 DIR_DEC); 247 break; 248 249 case PDCP_CIPHER_TYPE_AES: 250 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, WAITCOMP | IMMED); 251 252 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT); 253 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CTR, 254 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, 255 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : 256 DIR_DEC); 257 break; 258 259 case PDCP_CIPHER_TYPE_ZUC: 260 if (rta_sec_era < RTA_SEC_ERA_5) { 261 pr_err("Invalid era for selected algorithm\n"); 262 return -ENOTSUP; 263 } 264 265 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED); 266 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED); 267 268 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT); 269 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE, OP_ALG_AAI_F8, 270 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, 271 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : 272 DIR_DEC); 273 break; 274 275 default: 276 pr_err("%s: Invalid encrypt algorithm selected: %d\n", 277 "pdcp_sdap_insert_enc_only_op", cipherdata->algtype); 278 return -EINVAL; 279 } 280 281 if (dir == OP_TYPE_ENCAP_PROTOCOL) { 282 SEQFIFOLOAD(p, MSG1, 0, VLF); 283 FIFOLOAD(p, MSG1, PDCP_NULL_INT_MAC_I_VAL, 4, 284 LAST1 | FLUSH1 | IMMED); 285 } else { 286 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1); 287 MOVE(p, OFIFO, 0, MATH1, 4, PDCP_MAC_I_LEN, WAITCOMP | IMMED); 288 MATHB(p, MATH1, XOR, PDCP_NULL_INT_MAC_I_VAL, NONE, 4, IMMED2); 289 JUMP(p, PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS, HALT_STATUS, 290 ALL_FALSE, MATH_Z); 291 } 292 293 return 0; 294 } 295 296 /* 297 * This function leverage the use of in/out snooping as SNOW and ZUC both 298 * have a class 1 and class 2 CHA. It also supports AES as cipher. 299 * Supported: 300 * - cipher: 301 * - AES-CTR 302 * - SNOW F8 303 * - ZUC F8 304 * - authentication 305 * - SNOW F8 306 * - ZUC F8 307 */ 308 static inline int 309 pdcp_sdap_insert_snoop_op(struct program *p, bool swap __maybe_unused, 310 struct alginfo *cipherdata, struct alginfo *authdata, 311 unsigned int dir, enum pdcp_sn_size sn_size, 312 unsigned char era_2_sw_hfn_ovrd __maybe_unused) 313 { 314 uint32_t offset = 0, length = 0, sn_mask = 0; 315 uint32_t int_op_alg = 0; 316 uint32_t int_op_aai = 0; 317 uint32_t cipher_op_alg = 0; 318 uint32_t cipher_op_aai = 0; 319 320 if (authdata->algtype == PDCP_CIPHER_TYPE_ZUC) { 321 if (rta_sec_era < RTA_SEC_ERA_5) { 322 pr_err("Invalid era for selected algorithm\n"); 323 return -ENOTSUP; 324 } 325 } 326 327 if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length, 328 &sn_mask)) 329 return -ENOTSUP; 330 331 if (dir == OP_TYPE_ENCAP_PROTOCOL) 332 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2); 333 334 key_loading_opti(p, cipherdata, authdata); 335 336 /* Load the PDCP header from the input data 337 * Note: SEQINSZ is decremented by length 338 */ 339 SEQLOAD(p, MATH0, offset, length, 0); 340 /* Wait the SN is loaded */ 341 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM); 342 343 /* Pass the PDCP header to integrity block */ 344 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED); 345 346 #ifdef SDAP_SUPPORT 347 /* If SDAP is enabled, the least significant byte is the SDAP header 348 * Remove it by shifting the register 349 */ 350 rta_mathi(p, MATH0, 351 ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT), 352 SDAP_BITS_SIZE, MATH1, 8, 0); 353 /* Mask the PDCP header to keep only the SN */ 354 MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2); 355 #else 356 /* Mask the PDCP header to keep only the SN */ 357 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2); 358 #endif 359 360 /* Do a byte swap, it places the SN in upper part of the MATH reg */ 361 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0); 362 363 /* Load the HFN / Beare / Dir from the PDB 364 * CAAM word are 32bit hence loading 8 byte loads 2 words: 365 * - The HFN at offset 8 366 * - The Bearer / Dir at offset 12 367 */ 368 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED); 369 /* Create the 4 first byte of the ICV by oring the math registers */ 370 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0); 371 372 /* Set the IV of class 1 CHA */ 373 if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) { 374 MOVEB(p, MATH1, 0, CONTEXT1, 16, 8, IMMED); 375 } else { 376 /* Set the IV for the confidentiality CHA */ 377 MOVEB(p, MATH1, 0, CONTEXT1, 0, 8, IMMED); 378 } 379 380 /* Set the IV of class 2 CHA */ 381 if (authdata->algtype == PDCP_AUTH_TYPE_ZUC) { 382 /* Set the IV for the integrity CHA */ 383 MOVEB(p, MATH1, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED); 384 } else if (authdata->algtype == PDCP_AUTH_TYPE_SNOW) { 385 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, WAITCOMP | IMMED); 386 387 /* Generate the bottom snow IV for integrity 388 * Note: MATH1 lowest 32bits is as follow: 389 * | bearer (5) | Dir (1) | zero (26) | 390 * the resulting math regs will be: 391 * MATH3 MATH2 392 * | zero (5) | Dir (1) | zero (26) | | Bearer (5) | zero (27) | 393 */ 394 if (swap == false) { 395 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK), 396 MATH2, 4, IMMED2); 397 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK), 398 MATH3, 4, IMMED2); 399 } else { 400 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE), 401 MATH2, 4, IMMED2); 402 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE), 403 MATH3, 4, IMMED2); 404 } 405 /* Word swap MATH3 reg */ 406 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0); 407 408 /* Don't understand, seems to be doing a move of 12 byte 409 * (read MATH2 and overread MATH3) 410 */ 411 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED); 412 413 /* Add the rest of the snow IV to the context */ 414 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED); 415 } 416 417 /* Set the variable size of data the register will write */ 418 if (dir == OP_TYPE_ENCAP_PROTOCOL) { 419 /* We will add the interity data so add its length */ 420 MATHI(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2); 421 } else { 422 /* We will check the interity data so remove its length */ 423 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2); 424 /* Do not take the ICV in the out-snooping configuration */ 425 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQINSZ, 4, IMMED2); 426 } 427 428 /* We write the PDCP header to output*/ 429 SEQSTORE(p, MATH0, offset, length, 0); 430 431 /* Definition of the flow of output data */ 432 if (dir == OP_TYPE_ENCAP_PROTOCOL) { 433 /* We write data according to VSEQOUTSZ */ 434 SEQFIFOSTORE(p, MSG, 0, 0, VLF); 435 } else { 436 /* We write data according to VSEQOUTSZ */ 437 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT); 438 } 439 440 /* Get parameters for authentication */ 441 if (authdata->algtype == PDCP_AUTH_TYPE_ZUC) { 442 int_op_alg = OP_ALG_ALGSEL_ZUCA; 443 int_op_aai = OP_ALG_AAI_F9; 444 } else if (authdata->algtype == PDCP_AUTH_TYPE_SNOW) { 445 int_op_alg = OP_ALG_ALGSEL_SNOW_F9; 446 int_op_aai = OP_ALG_AAI_F9; 447 } else { 448 pr_err("%s no support for auth alg: %d\n", __func__, 449 authdata->algtype); 450 return -1; 451 } 452 453 /* Get parameters for ciphering */ 454 if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) { 455 cipher_op_alg = OP_ALG_ALGSEL_ZUCE; 456 cipher_op_aai = OP_ALG_AAI_F8; 457 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) { 458 cipher_op_alg = OP_ALG_ALGSEL_SNOW_F8; 459 cipher_op_aai = OP_ALG_AAI_F8; 460 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) { 461 cipher_op_alg = OP_ALG_ALGSEL_AES; 462 cipher_op_aai = OP_ALG_AAI_CTR; 463 } else { 464 pr_err("%s no support for cipher alg: %d\n", __func__, 465 authdata->algtype); 466 return -1; 467 } 468 469 /* Configure the CHA, the class 2 CHA must be configured first or an 470 * error will be generated 471 */ 472 473 /* Configure the class 2 CHA (integrity )*/ 474 ALG_OPERATION(p, int_op_alg, int_op_aai, OP_ALG_AS_INITFINAL, 475 dir == OP_TYPE_ENCAP_PROTOCOL ? ICV_CHECK_DISABLE : 476 ICV_CHECK_ENABLE, 477 DIR_ENC); 478 479 /* Configure class 1 CHA (confidentiality)*/ 480 ALG_OPERATION(p, cipher_op_alg, cipher_op_aai, OP_ALG_AS_INITFINAL, 481 ICV_CHECK_DISABLE, 482 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC); 483 484 /* Definition of the flow of input data */ 485 if (dir == OP_TYPE_ENCAP_PROTOCOL) { 486 /* We read data according to VSEQINSZ 487 * Note: we perform an in-snooping, eg the data will be read 488 * only once. they will be sent to both the integrity CHA and 489 * confidentiality CHA 490 */ 491 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2); 492 493 /* When the integrity CHA is finished, send the ICV stored in 494 * the context to the confidentiality CHA for encryption 495 */ 496 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED); 497 } else { 498 /* We read data according to VSEQINSZ 499 * Note: we perform an out-snooping, eg the data will be read 500 * only once. The will first be sent to the confidentiality 501 * CHA for decryption, then the CAAM will direct them to the 502 * integrity CHA to verify the ICV (which is at the end of the 503 * sequence) 504 */ 505 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2); 506 507 /* Process the ICV by class 1 CHA */ 508 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1); 509 510 /* Wait for class 1 CHA to finish, the ICV data are stalling in 511 * the output fifo 512 */ 513 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP); 514 515 if (rta_sec_era >= RTA_SEC_ERA_6) 516 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED); 517 518 /* Save the content left in the Output FIFO (the ICV) to MATH0 519 */ 520 MOVE(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED); 521 522 /* Configure a NFIFO entry to take data from the altsource 523 * and send it to the class 2 CHA as an ICV 524 */ 525 NFIFOADD(p, IFIFO, ICV2, 4, LAST2); 526 527 /* Move the content of MATH0 (OFIFO offset) to altsource 528 * Note: As configured by the altsource, this will send 529 * the 530 */ 531 if (rta_sec_era <= RTA_SEC_ERA_2) { 532 /* Shut off automatic Info FIFO entries */ 533 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED); 534 MOVE(p, MATH0, 0, IFIFOAB2, 0, 4, WAITCOMP | IMMED); 535 } else { 536 MOVE(p, MATH0, 0, IFIFO, 0, 4, WAITCOMP | IMMED); 537 } 538 } 539 540 if (authdata->algtype == PDCP_CIPHER_TYPE_ZUC) { 541 /* Reset ZUCA mode and done interrupt 542 * Note: If it is not done, DECO generate an error: 200031ca 543 * -> ZUCA ICV failed 544 */ 545 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED); 546 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED); 547 } 548 549 return 0; 550 } 551 552 /* Function used when the integrity algorithm is a class 1 CHA so outsnooping 553 * is not possible 554 * Supported: 555 * - cipher: 556 * - AES-CTR 557 * - SNOW F8 558 * - ZUC F8 559 * - authentication 560 * - AES-CMAC 561 */ 562 static inline int pdcp_sdap_insert_no_snoop_op( 563 struct program *p, bool swap __maybe_unused, struct alginfo *cipherdata, 564 struct alginfo *authdata, unsigned int dir, enum pdcp_sn_size sn_size, 565 unsigned char era_2_sw_hfn_ovrd __maybe_unused) 566 { 567 uint32_t offset = 0, length = 0, sn_mask = 0; 568 uint32_t cipher_alg_op = 0; 569 uint32_t cipher_alg_aai = 0; 570 571 if (authdata->algtype == PDCP_CIPHER_TYPE_ZUC) { 572 if (rta_sec_era < RTA_SEC_ERA_5) { 573 pr_err("Invalid era for selected algorithm\n"); 574 return -ENOTSUP; 575 } 576 } 577 578 if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length, 579 &sn_mask)) 580 return -ENOTSUP; 581 582 SEQLOAD(p, MATH0, offset, length, 0); 583 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM); 584 585 #ifdef SDAP_SUPPORT 586 rta_mathi(p, MATH0, 587 ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT), 588 SDAP_BITS_SIZE, MATH1, 8, 0); 589 MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2); 590 #else 591 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2); 592 #endif 593 594 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0); 595 MOVEB(p, DESCBUF, 8, MATH2, 0, 0x08, WAITCOMP | IMMED); 596 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0); 597 598 SEQSTORE(p, MATH0, offset, length, 0); 599 600 if (dir == OP_TYPE_ENCAP_PROTOCOL) { 601 /* Load authentication key */ 602 KEY(p, KEY1, authdata->key_enc_flags, authdata->key, 603 authdata->keylen, INLINE_KEY(authdata)); 604 605 /* Set the iv for AES authentication */ 606 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 8, IMMED); 607 608 /* Pass the header */ 609 MOVEB(p, MATH0, offset, IFIFOAB1, 0, length, IMMED); 610 611 /* Configure variable size for I/O */ 612 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0); 613 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2); 614 615 /* Perform the authentication */ 616 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CMAC, 617 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_DEC); 618 619 /* Configure the read of data */ 620 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1); 621 622 /* Save the ICV generated */ 623 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED); 624 625 /* The CHA will be reused so we need to clear it */ 626 LOAD(p, CLRW_RESET_CLS1_CHA | 627 CLRW_CLR_C1KEY | 628 CLRW_CLR_C1CTX | 629 CLRW_CLR_C1ICV | 630 CLRW_CLR_C1DATAS | 631 CLRW_CLR_C1MODE, 632 CLRW, 0, 4, IMMED); 633 634 /* Load confidentiality key */ 635 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key, 636 cipherdata->keylen, INLINE_KEY(cipherdata)); 637 638 /* Load the IV for ciphering */ 639 if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) { 640 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED); 641 cipher_alg_op = OP_ALG_ALGSEL_AES; 642 cipher_alg_aai = OP_ALG_AAI_CTR; 643 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) { 644 /* Set the IV for the confidentiality CHA */ 645 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED); 646 cipher_alg_op = OP_ALG_ALGSEL_ZUCE; 647 cipher_alg_aai = OP_ALG_AAI_F8; 648 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) { 649 /* Set the IV for the confidentiality CHA */ 650 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED); 651 cipher_alg_op = OP_ALG_ALGSEL_SNOW_F8; 652 cipher_alg_aai = OP_ALG_AAI_F8; 653 } 654 655 /* Rewind the pointer on input data to reread it */ 656 SEQINPTR(p, 0, PDCP_NULL_MAX_FRAME_LEN, RTO); 657 658 /* Define the ciphering operation */ 659 ALG_OPERATION(p, cipher_alg_op, cipher_alg_aai, 660 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC); 661 662 /* Define the data to write */ 663 SEQFIFOSTORE(p, MSG, 0, 0, VLF); 664 665 /* Skip the header which does not need to be encrypted */ 666 SEQFIFOLOAD(p, SKIP, length, 0); 667 668 /* Read the rest of the data */ 669 SEQFIFOLOAD(p, MSG1, 0, VLF); 670 671 /* Send the ICV stored in MATH3 for encryption */ 672 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED); 673 } else { 674 /* Load the IV for ciphering */ 675 if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) { 676 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED); 677 cipher_alg_op = OP_ALG_ALGSEL_AES; 678 cipher_alg_aai = OP_ALG_AAI_CTR; 679 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) { 680 /* Set the IV for the confidentiality CHA */ 681 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED); 682 cipher_alg_op = OP_ALG_ALGSEL_ZUCE; 683 cipher_alg_aai = OP_ALG_AAI_F8; 684 } else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) { 685 /* Set the IV for the confidentiality CHA */ 686 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED); 687 cipher_alg_op = OP_ALG_ALGSEL_SNOW_F8; 688 cipher_alg_aai = OP_ALG_AAI_F8; 689 } 690 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, IMMED); 691 692 /* Read all the data */ 693 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0); 694 695 /* Do not write back the ICV */ 696 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2); 697 698 /* Load the key for ciphering */ 699 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key, 700 cipherdata->keylen, INLINE_KEY(cipherdata)); 701 702 /* Write all the data */ 703 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT); 704 705 /* Define the ciphering algorithm */ 706 ALG_OPERATION(p, cipher_alg_op, cipher_alg_aai, 707 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_DEC); 708 709 /* Read all the data */ 710 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1); 711 712 /* Save the ICV which is stalling in output FIFO to MATH3 */ 713 MOVEB(p, OFIFO, 0, MATH3, 0, 4, IMMED); 714 715 /* Reset class 1 CHA */ 716 LOAD(p, CLRW_RESET_CLS1_CHA | 717 CLRW_CLR_C1KEY | 718 CLRW_CLR_C1CTX | 719 CLRW_CLR_C1ICV | 720 CLRW_CLR_C1DATAS | 721 CLRW_CLR_C1MODE, 722 CLRW, 0, 4, IMMED); 723 724 /* Load the key for authentcation */ 725 KEY(p, KEY1, authdata->key_enc_flags, authdata->key, 726 authdata->keylen, INLINE_KEY(authdata)); 727 728 /* Start a new sequence */ 729 SEQINPTR(p, 0, 0, SOP); 730 731 /* Define the operation to verify the ICV */ 732 ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CMAC, 733 OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC); 734 735 /* Set the variable size input */ 736 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0); 737 738 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED); 739 740 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1); 741 742 /* Define an NFIFO entry to load the ICV saved */ 743 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE | 744 NFIFOENTRY_DEST_CLASS1 | 745 NFIFOENTRY_DTYPE_ICV | 746 NFIFOENTRY_LC1 | 747 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED); 748 749 /* Load the ICV */ 750 MOVEB(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED); 751 } 752 753 return 0; 754 } 755 756 static int pdcp_sdap_insert_with_int_op( 757 struct program *p, bool swap __maybe_unused, struct alginfo *cipherdata, 758 struct alginfo *authdata, enum pdcp_sn_size sn_size, 759 unsigned char era_2_sw_hfn_ovrd, unsigned int dir) 760 { 761 static int ( 762 *pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])( 763 struct program *, bool swap, struct alginfo *, struct alginfo *, 764 unsigned int, enum pdcp_sn_size, 765 unsigned char __maybe_unused) = { 766 { 767 /* NULL */ 768 pdcp_insert_cplane_null_op, /* NULL */ 769 pdcp_insert_cplane_int_only_op, /* SNOW f9 */ 770 pdcp_insert_cplane_int_only_op, /* AES CMAC */ 771 pdcp_insert_cplane_int_only_op /* ZUC-I */ 772 }, 773 { 774 /* SNOW f8 */ 775 pdcp_sdap_insert_enc_only_op, /* NULL */ 776 pdcp_sdap_insert_snoop_op, /* SNOW f9 */ 777 pdcp_sdap_insert_no_snoop_op, /* AES CMAC */ 778 pdcp_sdap_insert_snoop_op /* ZUC-I */ 779 }, 780 { 781 /* AES CTR */ 782 pdcp_sdap_insert_enc_only_op, /* NULL */ 783 pdcp_sdap_insert_snoop_op, /* SNOW f9 */ 784 pdcp_sdap_insert_no_snoop_op, /* AES CMAC */ 785 pdcp_sdap_insert_snoop_op /* ZUC-I */ 786 }, 787 { 788 /* ZUC-E */ 789 pdcp_sdap_insert_enc_only_op, /* NULL */ 790 pdcp_sdap_insert_snoop_op, /* SNOW f9 */ 791 pdcp_sdap_insert_no_snoop_op, /* AES CMAC */ 792 pdcp_sdap_insert_snoop_op /* ZUC-I */ 793 }, 794 }; 795 int err; 796 797 err = pdcp_cp_fp[cipherdata->algtype] 798 [authdata->algtype](p, swap, cipherdata, authdata, dir, 799 sn_size, era_2_sw_hfn_ovrd); 800 if (err) 801 return err; 802 803 return 0; 804 } 805 806 static inline int 807 cnstr_shdsc_pdcp_sdap_u_plane(uint32_t *descbuf, 808 bool ps, 809 bool swap, 810 enum pdcp_sn_size sn_size, 811 uint32_t hfn, 812 unsigned short bearer, 813 unsigned short direction, 814 uint32_t hfn_threshold, 815 struct alginfo *cipherdata, 816 struct alginfo *authdata, 817 unsigned char era_2_sw_hfn_ovrd, 818 uint32_t caps_mode) 819 { 820 struct program prg; 821 struct program *p = &prg; 822 int err; 823 enum pdb_type_e pdb_type; 824 static enum rta_share_type 825 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = { 826 { 827 /* NULL */ 828 SHR_WAIT, /* NULL */ 829 SHR_ALWAYS, /* SNOW f9 */ 830 SHR_ALWAYS, /* AES CMAC */ 831 SHR_ALWAYS /* ZUC-I */ 832 }, 833 { 834 /* SNOW f8 */ 835 SHR_ALWAYS, /* NULL */ 836 SHR_ALWAYS, /* SNOW f9 */ 837 SHR_WAIT, /* AES CMAC */ 838 SHR_WAIT /* ZUC-I */ 839 }, 840 { 841 /* AES CTR */ 842 SHR_ALWAYS, /* NULL */ 843 SHR_ALWAYS, /* SNOW f9 */ 844 SHR_ALWAYS, /* AES CMAC */ 845 SHR_WAIT /* ZUC-I */ 846 }, 847 { 848 /* ZUC-E */ 849 SHR_ALWAYS, /* NULL */ 850 SHR_WAIT, /* SNOW f9 */ 851 SHR_WAIT, /* AES CMAC */ 852 SHR_WAIT /* ZUC-I */ 853 }, 854 }; 855 856 LABEL(pdb_end); 857 858 /* Check HFN override for ERA 2 */ 859 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) { 860 pr_err("Cannot select SW HFN ovrd for other era than 2"); 861 return -EINVAL; 862 } 863 864 /* Check the confidentiality algorithm is supported by the code */ 865 switch (cipherdata->algtype) { 866 case PDCP_CIPHER_TYPE_NULL: 867 case PDCP_CIPHER_TYPE_SNOW: 868 case PDCP_CIPHER_TYPE_AES: 869 case PDCP_CIPHER_TYPE_ZUC: 870 break; 871 default: 872 pr_err("Cipher algorithm not supported: %d\n", 873 cipherdata->algtype); 874 return -ENOTSUP; 875 } 876 877 /* Check the authentication algorithm is supported by the code */ 878 if (authdata) { 879 switch (authdata->algtype) { 880 case PDCP_AUTH_TYPE_NULL: 881 case PDCP_AUTH_TYPE_SNOW: 882 case PDCP_AUTH_TYPE_AES: 883 case PDCP_AUTH_TYPE_ZUC: 884 break; 885 default: 886 pr_err("Auth algorithm not supported: %d\n", 887 authdata->algtype); 888 return -ENOTSUP; 889 } 890 } 891 892 /* Check the Sequence Number size is supported by the code */ 893 switch (sn_size) { 894 case PDCP_SN_SIZE_5: 895 case PDCP_SN_SIZE_7: 896 case PDCP_SN_SIZE_12: 897 case PDCP_SN_SIZE_15: 898 case PDCP_SN_SIZE_18: 899 break; 900 default: 901 pr_err("SN size not supported: %d\n", sn_size); 902 return -ENOTSUP; 903 } 904 905 /* Check that we are not performing ZUC algo on old platforms */ 906 if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC && 907 rta_sec_era < RTA_SEC_ERA_5) { 908 pr_err("ZUC algorithm not supported for era: %d\n", 909 rta_sec_era); 910 return -ENOTSUP; 911 } 912 913 /* Initialize the program */ 914 PROGRAM_CNTXT_INIT(p, descbuf, 0); 915 916 if (swap) 917 PROGRAM_SET_BSWAP(p); 918 919 if (ps) 920 PROGRAM_SET_36BIT_ADDR(p); 921 922 /* Select the shared descriptor sharing mode */ 923 if (authdata) 924 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 925 0, 0); 926 else 927 SHR_HDR(p, SHR_ALWAYS, 0, 0); 928 929 /* Construct the PDB */ 930 pdb_type = cnstr_pdcp_u_plane_pdb(p, sn_size, hfn, bearer, direction, 931 hfn_threshold, cipherdata, authdata); 932 if (pdb_type == PDCP_PDB_TYPE_INVALID) { 933 pr_err("Error creating PDCP UPlane PDB\n"); 934 return -EINVAL; 935 } 936 SET_LABEL(p, pdb_end); 937 938 /* Inser the HFN override operation */ 939 err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd); 940 if (err) 941 return err; 942 943 /* Create the descriptor */ 944 if (!authdata) { 945 if (cipherdata->algtype == PDCP_CIPHER_TYPE_NULL) { 946 insert_copy_frame_op(p, cipherdata, 947 OP_TYPE_ENCAP_PROTOCOL); 948 } else { 949 err = pdcp_sdap_insert_no_int_op(p, swap, cipherdata, 950 caps_mode, 951 sn_size); 952 if (err) { 953 pr_err("Fail pdcp_sdap_insert_no_int_op\n"); 954 return err; 955 } 956 } 957 } else { 958 err = pdcp_sdap_insert_with_int_op(p, swap, cipherdata, 959 authdata, sn_size, 960 era_2_sw_hfn_ovrd, 961 caps_mode); 962 if (err) { 963 pr_err("Fail pdcp_sdap_insert_with_int_op\n"); 964 return err; 965 } 966 } 967 968 PATCH_HDR(p, 0, pdb_end); 969 970 return PROGRAM_FINALIZE(p); 971 } 972 973 /** 974 * cnstr_shdsc_pdcp_sdap_u_plane_encap - Function for creating a PDCP-SDAP 975 * User Plane encapsulation descriptor. 976 * @descbuf: pointer to buffer for descriptor construction 977 * @ps: if 36/40bit addressing is desired, this parameter must be true 978 * @swap: must be true when core endianness doesn't match SEC endianness 979 * @sn_size: selects Sequence Number Size: 7/12/15 bits 980 * @hfn: starting Hyper Frame Number to be used together with the SN from the 981 * PDCP frames. 982 * @bearer: radio bearer ID 983 * @direction: the direction of the PDCP frame (UL/DL) 984 * @hfn_threshold: HFN value that once reached triggers a warning from SEC that 985 * keys should be renegotiated at the earliest convenience. 986 * @cipherdata: pointer to block cipher transform definitions 987 * Valid algorithm values are those from cipher_type_pdcp enum. 988 * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for 989 * this descriptor. Note: Can only be used for 990 * SEC ERA 2. 991 * 992 * Return: size of descriptor written in words or negative number on error. 993 * Once the function returns, the value of this parameter can be used 994 * for reclaiming the space that wasn't used for the descriptor. 995 * 996 * Note: descbuf must be large enough to contain a full 256 byte long 997 * descriptor; after the function returns, by subtracting the actual number of 998 * bytes used, the user can reuse the remaining buffer space for other purposes. 999 */ 1000 static inline int 1001 cnstr_shdsc_pdcp_sdap_u_plane_encap(uint32_t *descbuf, 1002 bool ps, 1003 bool swap, 1004 enum pdcp_sn_size sn_size, 1005 uint32_t hfn, 1006 unsigned short bearer, 1007 unsigned short direction, 1008 uint32_t hfn_threshold, 1009 struct alginfo *cipherdata, 1010 struct alginfo *authdata, 1011 unsigned char era_2_sw_hfn_ovrd) 1012 { 1013 return cnstr_shdsc_pdcp_sdap_u_plane(descbuf, ps, swap, sn_size, 1014 hfn, bearer, direction, hfn_threshold, cipherdata, 1015 authdata, era_2_sw_hfn_ovrd, OP_TYPE_ENCAP_PROTOCOL); 1016 } 1017 1018 /** 1019 * cnstr_shdsc_pdcp_sdap_u_plane_decap - Function for creating a PDCP-SDAP 1020 * User Plane decapsulation descriptor. 1021 * @descbuf: pointer to buffer for descriptor construction 1022 * @ps: if 36/40bit addressing is desired, this parameter must be true 1023 * @swap: must be true when core endianness doesn't match SEC endianness 1024 * @sn_size: selects Sequence Number Size: 7/12/15 bits 1025 * @hfn: starting Hyper Frame Number to be used together with the SN from the 1026 * PDCP frames. 1027 * @bearer: radio bearer ID 1028 * @direction: the direction of the PDCP frame (UL/DL) 1029 * @hfn_threshold: HFN value that once reached triggers a warning from SEC that 1030 * keys should be renegotiated at the earliest convenience. 1031 * @cipherdata: pointer to block cipher transform definitions 1032 * Valid algorithm values are those from cipher_type_pdcp enum. 1033 * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for 1034 * this descriptor. Note: Can only be used for 1035 * SEC ERA 2. 1036 * 1037 * Return: size of descriptor written in words or negative number on error. 1038 * Once the function returns, the value of this parameter can be used 1039 * for reclaiming the space that wasn't used for the descriptor. 1040 * 1041 * Note: descbuf must be large enough to contain a full 256 byte long 1042 * descriptor; after the function returns, by subtracting the actual number of 1043 * bytes used, the user can reuse the remaining buffer space for other purposes. 1044 */ 1045 static inline int 1046 cnstr_shdsc_pdcp_sdap_u_plane_decap(uint32_t *descbuf, 1047 bool ps, 1048 bool swap, 1049 enum pdcp_sn_size sn_size, 1050 uint32_t hfn, 1051 unsigned short bearer, 1052 unsigned short direction, 1053 uint32_t hfn_threshold, 1054 struct alginfo *cipherdata, 1055 struct alginfo *authdata, 1056 unsigned char era_2_sw_hfn_ovrd) 1057 { 1058 return cnstr_shdsc_pdcp_sdap_u_plane(descbuf, ps, swap, sn_size, hfn, 1059 bearer, direction, hfn_threshold, cipherdata, authdata, 1060 era_2_sw_hfn_ovrd, OP_TYPE_DECAP_PROTOCOL); 1061 } 1062 1063 #endif /* __DESC_SDAP_H__ */ 1064