1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0) 2 * 3 * Copyright 2008-2016 Freescale Semiconductor Inc. 4 * Copyright 2016,2019-2021 NXP 5 */ 6 7 #ifndef __RTA_OPERATION_CMD_H__ 8 #define __RTA_OPERATION_CMD_H__ 9 10 #if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 70000) 11 #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" 12 #endif 13 14 extern enum rta_sec_era rta_sec_era; 15 16 static inline int 17 __rta_alg_aai_aes(uint16_t aai) 18 { 19 uint16_t aes_mode = aai & OP_ALG_AESA_MODE_MASK; 20 21 if (aai & OP_ALG_AAI_C2K) { 22 if (rta_sec_era < RTA_SEC_ERA_5) 23 return -1; 24 if ((aes_mode != OP_ALG_AAI_CCM) && 25 (aes_mode != OP_ALG_AAI_GCM)) 26 return -EINVAL; 27 } 28 29 switch (aes_mode) { 30 case OP_ALG_AAI_CBC_CMAC: 31 case OP_ALG_AAI_CTR_CMAC_LTE: 32 case OP_ALG_AAI_CTR_CMAC: 33 if (rta_sec_era < RTA_SEC_ERA_2) 34 return -EINVAL; 35 /* no break */ 36 case OP_ALG_AAI_CTR: 37 case OP_ALG_AAI_CBC: 38 case OP_ALG_AAI_ECB: 39 case OP_ALG_AAI_OFB: 40 case OP_ALG_AAI_CFB: 41 case OP_ALG_AAI_XTS: 42 case OP_ALG_AAI_CMAC: 43 case OP_ALG_AAI_XCBC_MAC: 44 case OP_ALG_AAI_CCM: 45 case OP_ALG_AAI_GCM: 46 case OP_ALG_AAI_CBC_XCBCMAC: 47 case OP_ALG_AAI_CTR_XCBCMAC: 48 return 0; 49 } 50 51 return -EINVAL; 52 } 53 54 static inline int 55 __rta_alg_aai_des(uint16_t aai) 56 { 57 uint16_t aai_code = (uint16_t)(aai & ~OP_ALG_AAI_CHECKODD); 58 59 switch (aai_code) { 60 case OP_ALG_AAI_CBC: 61 case OP_ALG_AAI_ECB: 62 case OP_ALG_AAI_CFB: 63 case OP_ALG_AAI_OFB: 64 return 0; 65 } 66 67 return -EINVAL; 68 } 69 70 static inline int 71 __rta_alg_aai_md5(uint16_t aai) 72 { 73 switch (aai) { 74 case OP_ALG_AAI_HMAC: 75 if (rta_sec_era < RTA_SEC_ERA_2) 76 return -EINVAL; 77 /* no break */ 78 case OP_ALG_AAI_SMAC: 79 case OP_ALG_AAI_HASH: 80 case OP_ALG_AAI_HMAC_PRECOMP: 81 return 0; 82 } 83 84 return -EINVAL; 85 } 86 87 static inline int 88 __rta_alg_aai_sha(uint16_t aai) 89 { 90 switch (aai) { 91 case OP_ALG_AAI_HMAC: 92 if (rta_sec_era < RTA_SEC_ERA_2) 93 return -EINVAL; 94 /* no break */ 95 case OP_ALG_AAI_HASH: 96 case OP_ALG_AAI_HMAC_PRECOMP: 97 return 0; 98 } 99 100 return -EINVAL; 101 } 102 103 static inline int 104 __rta_alg_aai_rng(uint16_t aai) 105 { 106 uint16_t rng_mode = aai & OP_ALG_RNG_MODE_MASK; 107 uint16_t rng_sh = aai & OP_ALG_AAI_RNG4_SH_MASK; 108 109 switch (rng_mode) { 110 case OP_ALG_AAI_RNG: 111 case OP_ALG_AAI_RNG_NZB: 112 case OP_ALG_AAI_RNG_OBP: 113 break; 114 default: 115 return -EINVAL; 116 } 117 118 /* State Handle bits are valid only for SEC Era >= 5 */ 119 if ((rta_sec_era < RTA_SEC_ERA_5) && rng_sh) 120 return -EINVAL; 121 122 /* PS, AI, SK bits are also valid only for SEC Era >= 5 */ 123 if ((rta_sec_era < RTA_SEC_ERA_5) && (aai & 124 (OP_ALG_AAI_RNG4_PS | OP_ALG_AAI_RNG4_AI | OP_ALG_AAI_RNG4_SK))) 125 return -EINVAL; 126 127 switch (rng_sh) { 128 case OP_ALG_AAI_RNG4_SH_0: 129 case OP_ALG_AAI_RNG4_SH_1: 130 return 0; 131 } 132 133 return -EINVAL; 134 } 135 136 static inline int 137 __rta_alg_aai_crc(uint16_t aai) 138 { 139 uint16_t aai_code = aai & OP_ALG_CRC_POLY_MASK; 140 141 switch (aai_code) { 142 case OP_ALG_AAI_802: 143 case OP_ALG_AAI_3385: 144 case OP_ALG_AAI_CUST_POLY: 145 return 0; 146 } 147 148 return -EINVAL; 149 } 150 151 static inline int 152 __rta_alg_aai_kasumi(uint16_t aai) 153 { 154 switch (aai) { 155 case OP_ALG_AAI_GSM: 156 case OP_ALG_AAI_EDGE: 157 case OP_ALG_AAI_F8: 158 case OP_ALG_AAI_F9: 159 return 0; 160 } 161 162 return -EINVAL; 163 } 164 165 static inline int 166 __rta_alg_aai_snow_f9(uint16_t aai) 167 { 168 if (aai == OP_ALG_AAI_F9) 169 return 0; 170 171 return -EINVAL; 172 } 173 174 static inline int 175 __rta_alg_aai_snow_f8(uint16_t aai) 176 { 177 if (aai == OP_ALG_AAI_F8) 178 return 0; 179 180 return -EINVAL; 181 } 182 183 static inline int 184 __rta_alg_aai_zuce(uint16_t aai) 185 { 186 if (aai == OP_ALG_AAI_F8) 187 return 0; 188 189 return -EINVAL; 190 } 191 192 static inline int 193 __rta_alg_aai_zuca(uint16_t aai) 194 { 195 if (aai == OP_ALG_AAI_F9) 196 return 0; 197 198 return -EINVAL; 199 } 200 201 struct alg_aai_map { 202 uint32_t chipher_algo; 203 int (*aai_func)(uint16_t); 204 uint32_t class; 205 }; 206 207 static const struct alg_aai_map alg_table[] = { 208 /*1*/ { OP_ALG_ALGSEL_AES, __rta_alg_aai_aes, OP_TYPE_CLASS1_ALG }, 209 { OP_ALG_ALGSEL_DES, __rta_alg_aai_des, OP_TYPE_CLASS1_ALG }, 210 { OP_ALG_ALGSEL_3DES, __rta_alg_aai_des, OP_TYPE_CLASS1_ALG }, 211 { OP_ALG_ALGSEL_MD5, __rta_alg_aai_md5, OP_TYPE_CLASS2_ALG }, 212 { OP_ALG_ALGSEL_SHA1, __rta_alg_aai_md5, OP_TYPE_CLASS2_ALG }, 213 { OP_ALG_ALGSEL_SHA224, __rta_alg_aai_sha, OP_TYPE_CLASS2_ALG }, 214 { OP_ALG_ALGSEL_SHA256, __rta_alg_aai_sha, OP_TYPE_CLASS2_ALG }, 215 { OP_ALG_ALGSEL_SHA384, __rta_alg_aai_sha, OP_TYPE_CLASS2_ALG }, 216 { OP_ALG_ALGSEL_SHA512, __rta_alg_aai_sha, OP_TYPE_CLASS2_ALG }, 217 { OP_ALG_ALGSEL_RNG, __rta_alg_aai_rng, OP_TYPE_CLASS1_ALG }, 218 /*11*/ { OP_ALG_ALGSEL_CRC, __rta_alg_aai_crc, OP_TYPE_CLASS2_ALG }, 219 { OP_ALG_ALGSEL_ARC4, NULL, OP_TYPE_CLASS1_ALG }, 220 { OP_ALG_ALGSEL_SNOW_F8, __rta_alg_aai_snow_f8, OP_TYPE_CLASS1_ALG }, 221 /*14*/ { OP_ALG_ALGSEL_KASUMI, __rta_alg_aai_kasumi, OP_TYPE_CLASS1_ALG }, 222 { OP_ALG_ALGSEL_SNOW_F9, __rta_alg_aai_snow_f9, OP_TYPE_CLASS2_ALG }, 223 { OP_ALG_ALGSEL_ZUCE, __rta_alg_aai_zuce, OP_TYPE_CLASS1_ALG }, 224 /*17*/ { OP_ALG_ALGSEL_ZUCA, __rta_alg_aai_zuca, OP_TYPE_CLASS2_ALG } 225 }; 226 227 /* 228 * Allowed OPERATION algorithms for each SEC Era. 229 * Values represent the number of entries from alg_table[] that are supported. 230 */ 231 static const unsigned int alg_table_sz[] = {14, 15, 15, 15, 17, 17, 232 11, 17, 17, 17}; 233 234 static inline int 235 rta_operation(struct program *program, uint32_t cipher_algo, 236 uint16_t aai, uint8_t algo_state, 237 int icv_checking, int enc) 238 { 239 uint32_t opcode = CMD_OPERATION; 240 unsigned int i, found = 0; 241 unsigned int start_pc = program->current_pc; 242 int ret; 243 244 for (i = 0; i < alg_table_sz[rta_sec_era]; i++) { 245 if (alg_table[i].chipher_algo == cipher_algo) { 246 if ((aai == OP_ALG_AAI_XCBC_MAC) || 247 (aai == OP_ALG_AAI_CBC_XCBCMAC)) 248 opcode |= cipher_algo | OP_TYPE_CLASS2_ALG; 249 else 250 opcode |= cipher_algo | alg_table[i].class; 251 /* nothing else to verify */ 252 if (alg_table[i].aai_func == NULL) { 253 found = 1; 254 break; 255 } 256 257 aai &= OP_ALG_AAI_MASK; 258 259 ret = (*alg_table[i].aai_func)(aai); 260 if (ret < 0) { 261 pr_err("OPERATION: Bad AAI Type. SEC Program Line: %d\n", 262 program->current_pc); 263 goto err; 264 } 265 opcode |= aai; 266 found = 1; 267 break; 268 } 269 } 270 if (!found) { 271 pr_err("OPERATION: Invalid Command. SEC Program Line: %d\n", 272 program->current_pc); 273 ret = -EINVAL; 274 goto err; 275 } 276 277 switch (algo_state) { 278 case OP_ALG_AS_UPDATE: 279 case OP_ALG_AS_INIT: 280 case OP_ALG_AS_FINALIZE: 281 case OP_ALG_AS_INITFINAL: 282 opcode |= algo_state; 283 break; 284 default: 285 pr_err("Invalid Operation Command\n"); 286 ret = -EINVAL; 287 goto err; 288 } 289 290 switch (icv_checking) { 291 case ICV_CHECK_DISABLE: 292 /* 293 * opcode |= OP_ALG_ICV_OFF; 294 * OP_ALG_ICV_OFF is 0 295 */ 296 break; 297 case ICV_CHECK_ENABLE: 298 opcode |= OP_ALG_ICV_ON; 299 break; 300 default: 301 pr_err("Invalid Operation Command\n"); 302 ret = -EINVAL; 303 goto err; 304 } 305 306 switch (enc) { 307 case DIR_DEC: 308 /* 309 * opcode |= OP_ALG_DECRYPT; 310 * OP_ALG_DECRYPT is 0 311 */ 312 break; 313 case DIR_ENC: 314 opcode |= OP_ALG_ENCRYPT; 315 break; 316 default: 317 pr_err("Invalid Operation Command\n"); 318 ret = -EINVAL; 319 goto err; 320 } 321 322 __rta_out32(program, opcode); 323 program->current_instruction++; 324 return (int)start_pc; 325 326 err: 327 program->first_error_pc = start_pc; 328 return ret; 329 } 330 331 /* For non-proto offload CMAC, GMAC etc cases */ 332 static inline int 333 rta_operation2(struct program *program, uint32_t cipher_algo, 334 uint16_t aai, uint8_t algo_state, 335 int icv_checking, int enc) 336 { 337 uint32_t opcode = CMD_OPERATION; 338 unsigned int i, found = 0; 339 unsigned int start_pc = program->current_pc; 340 int ret; 341 342 for (i = 0; i < alg_table_sz[rta_sec_era]; i++) { 343 if (alg_table[i].chipher_algo == cipher_algo) { 344 if ((aai == OP_ALG_AAI_XCBC_MAC) || 345 (aai == OP_ALG_AAI_CBC_XCBCMAC) || 346 (aai == OP_ALG_AAI_CMAC)) 347 opcode |= cipher_algo | OP_TYPE_CLASS2_ALG; 348 else 349 opcode |= cipher_algo | alg_table[i].class; 350 /* nothing else to verify */ 351 if (alg_table[i].aai_func == NULL) { 352 found = 1; 353 break; 354 } 355 356 aai &= OP_ALG_AAI_MASK; 357 358 ret = (*alg_table[i].aai_func)(aai); 359 if (ret < 0) { 360 pr_err("OPERATION: Bad AAI Type. SEC Program Line: %d\n", 361 program->current_pc); 362 goto err; 363 } 364 opcode |= aai; 365 found = 1; 366 break; 367 } 368 } 369 if (!found) { 370 pr_err("OPERATION: Invalid Command. SEC Program Line: %d\n", 371 program->current_pc); 372 ret = -EINVAL; 373 goto err; 374 } 375 376 switch (algo_state) { 377 case OP_ALG_AS_UPDATE: 378 case OP_ALG_AS_INIT: 379 case OP_ALG_AS_FINALIZE: 380 case OP_ALG_AS_INITFINAL: 381 opcode |= algo_state; 382 break; 383 default: 384 pr_err("Invalid Operation Command\n"); 385 ret = -EINVAL; 386 goto err; 387 } 388 389 switch (icv_checking) { 390 case ICV_CHECK_DISABLE: 391 /* 392 * opcode |= OP_ALG_ICV_OFF; 393 * OP_ALG_ICV_OFF is 0 394 */ 395 break; 396 case ICV_CHECK_ENABLE: 397 opcode |= OP_ALG_ICV_ON; 398 break; 399 default: 400 pr_err("Invalid Operation Command\n"); 401 ret = -EINVAL; 402 goto err; 403 } 404 405 switch (enc) { 406 case DIR_DEC: 407 /* 408 * opcode |= OP_ALG_DECRYPT; 409 * OP_ALG_DECRYPT is 0 410 */ 411 break; 412 case DIR_ENC: 413 opcode |= OP_ALG_ENCRYPT; 414 break; 415 default: 416 pr_err("Invalid Operation Command\n"); 417 ret = -EINVAL; 418 goto err; 419 } 420 421 __rta_out32(program, opcode); 422 program->current_instruction++; 423 return (int)start_pc; 424 425 err: 426 program->first_error_pc = start_pc; 427 return ret; 428 } 429 430 /* 431 * OPERATION PKHA routines 432 */ 433 static inline int 434 __rta_pkha_clearmem(uint32_t pkha_op) 435 { 436 switch (pkha_op) { 437 case (OP_ALG_PKMODE_CLEARMEM_ALL): 438 case (OP_ALG_PKMODE_CLEARMEM_ABE): 439 case (OP_ALG_PKMODE_CLEARMEM_ABN): 440 case (OP_ALG_PKMODE_CLEARMEM_AB): 441 case (OP_ALG_PKMODE_CLEARMEM_AEN): 442 case (OP_ALG_PKMODE_CLEARMEM_AE): 443 case (OP_ALG_PKMODE_CLEARMEM_AN): 444 case (OP_ALG_PKMODE_CLEARMEM_A): 445 case (OP_ALG_PKMODE_CLEARMEM_BEN): 446 case (OP_ALG_PKMODE_CLEARMEM_BE): 447 case (OP_ALG_PKMODE_CLEARMEM_BN): 448 case (OP_ALG_PKMODE_CLEARMEM_B): 449 case (OP_ALG_PKMODE_CLEARMEM_EN): 450 case (OP_ALG_PKMODE_CLEARMEM_N): 451 case (OP_ALG_PKMODE_CLEARMEM_E): 452 return 0; 453 } 454 455 return -EINVAL; 456 } 457 458 static inline int 459 __rta_pkha_mod_arithmetic(uint32_t pkha_op) 460 { 461 pkha_op &= (uint32_t)~OP_ALG_PKMODE_OUT_A; 462 463 switch (pkha_op) { 464 case (OP_ALG_PKMODE_MOD_ADD): 465 case (OP_ALG_PKMODE_MOD_SUB_AB): 466 case (OP_ALG_PKMODE_MOD_SUB_BA): 467 case (OP_ALG_PKMODE_MOD_MULT): 468 case (OP_ALG_PKMODE_MOD_MULT_IM): 469 case (OP_ALG_PKMODE_MOD_MULT_IM_OM): 470 case (OP_ALG_PKMODE_MOD_EXPO): 471 case (OP_ALG_PKMODE_MOD_EXPO_TEQ): 472 case (OP_ALG_PKMODE_MOD_EXPO_IM): 473 case (OP_ALG_PKMODE_MOD_EXPO_IM_TEQ): 474 case (OP_ALG_PKMODE_MOD_REDUCT): 475 case (OP_ALG_PKMODE_MOD_INV): 476 case (OP_ALG_PKMODE_MOD_MONT_CNST): 477 case (OP_ALG_PKMODE_MOD_CRT_CNST): 478 case (OP_ALG_PKMODE_MOD_GCD): 479 case (OP_ALG_PKMODE_MOD_PRIMALITY): 480 case (OP_ALG_PKMODE_MOD_SML_EXP): 481 case (OP_ALG_PKMODE_F2M_ADD): 482 case (OP_ALG_PKMODE_F2M_MUL): 483 case (OP_ALG_PKMODE_F2M_MUL_IM): 484 case (OP_ALG_PKMODE_F2M_MUL_IM_OM): 485 case (OP_ALG_PKMODE_F2M_EXP): 486 case (OP_ALG_PKMODE_F2M_EXP_TEQ): 487 case (OP_ALG_PKMODE_F2M_AMODN): 488 case (OP_ALG_PKMODE_F2M_INV): 489 case (OP_ALG_PKMODE_F2M_R2): 490 case (OP_ALG_PKMODE_F2M_GCD): 491 case (OP_ALG_PKMODE_F2M_SML_EXP): 492 case (OP_ALG_PKMODE_ECC_F2M_ADD): 493 case (OP_ALG_PKMODE_ECC_F2M_ADD_IM_OM_PROJ): 494 case (OP_ALG_PKMODE_ECC_F2M_DBL): 495 case (OP_ALG_PKMODE_ECC_F2M_DBL_IM_OM_PROJ): 496 case (OP_ALG_PKMODE_ECC_F2M_MUL): 497 case (OP_ALG_PKMODE_ECC_F2M_MUL_TEQ): 498 case (OP_ALG_PKMODE_ECC_F2M_MUL_R2): 499 case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_TEQ): 500 case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_PROJ): 501 case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_PROJ_TEQ): 502 case (OP_ALG_PKMODE_ECC_MOD_ADD): 503 case (OP_ALG_PKMODE_ECC_MOD_ADD_IM_OM_PROJ): 504 case (OP_ALG_PKMODE_ECC_MOD_DBL): 505 case (OP_ALG_PKMODE_ECC_MOD_DBL_IM_OM_PROJ): 506 case (OP_ALG_PKMODE_ECC_MOD_MUL): 507 case (OP_ALG_PKMODE_ECC_MOD_MUL_TEQ): 508 case (OP_ALG_PKMODE_ECC_MOD_MUL_R2): 509 case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_TEQ): 510 case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_PROJ): 511 case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_PROJ_TEQ): 512 return 0; 513 } 514 515 return -EINVAL; 516 } 517 518 static inline int 519 __rta_pkha_copymem(uint32_t pkha_op) 520 { 521 switch (pkha_op) { 522 case (OP_ALG_PKMODE_COPY_NSZ_A0_B0): 523 case (OP_ALG_PKMODE_COPY_NSZ_A0_B1): 524 case (OP_ALG_PKMODE_COPY_NSZ_A0_B2): 525 case (OP_ALG_PKMODE_COPY_NSZ_A0_B3): 526 case (OP_ALG_PKMODE_COPY_NSZ_A1_B0): 527 case (OP_ALG_PKMODE_COPY_NSZ_A1_B1): 528 case (OP_ALG_PKMODE_COPY_NSZ_A1_B2): 529 case (OP_ALG_PKMODE_COPY_NSZ_A1_B3): 530 case (OP_ALG_PKMODE_COPY_NSZ_A2_B0): 531 case (OP_ALG_PKMODE_COPY_NSZ_A2_B1): 532 case (OP_ALG_PKMODE_COPY_NSZ_A2_B2): 533 case (OP_ALG_PKMODE_COPY_NSZ_A2_B3): 534 case (OP_ALG_PKMODE_COPY_NSZ_A3_B0): 535 case (OP_ALG_PKMODE_COPY_NSZ_A3_B1): 536 case (OP_ALG_PKMODE_COPY_NSZ_A3_B2): 537 case (OP_ALG_PKMODE_COPY_NSZ_A3_B3): 538 case (OP_ALG_PKMODE_COPY_NSZ_B0_A0): 539 case (OP_ALG_PKMODE_COPY_NSZ_B0_A1): 540 case (OP_ALG_PKMODE_COPY_NSZ_B0_A2): 541 case (OP_ALG_PKMODE_COPY_NSZ_B0_A3): 542 case (OP_ALG_PKMODE_COPY_NSZ_B1_A0): 543 case (OP_ALG_PKMODE_COPY_NSZ_B1_A1): 544 case (OP_ALG_PKMODE_COPY_NSZ_B1_A2): 545 case (OP_ALG_PKMODE_COPY_NSZ_B1_A3): 546 case (OP_ALG_PKMODE_COPY_NSZ_B2_A0): 547 case (OP_ALG_PKMODE_COPY_NSZ_B2_A1): 548 case (OP_ALG_PKMODE_COPY_NSZ_B2_A2): 549 case (OP_ALG_PKMODE_COPY_NSZ_B2_A3): 550 case (OP_ALG_PKMODE_COPY_NSZ_B3_A0): 551 case (OP_ALG_PKMODE_COPY_NSZ_B3_A1): 552 case (OP_ALG_PKMODE_COPY_NSZ_B3_A2): 553 case (OP_ALG_PKMODE_COPY_NSZ_B3_A3): 554 case (OP_ALG_PKMODE_COPY_NSZ_A_E): 555 case (OP_ALG_PKMODE_COPY_NSZ_A_N): 556 case (OP_ALG_PKMODE_COPY_NSZ_B_E): 557 case (OP_ALG_PKMODE_COPY_NSZ_B_N): 558 case (OP_ALG_PKMODE_COPY_NSZ_N_A): 559 case (OP_ALG_PKMODE_COPY_NSZ_N_B): 560 case (OP_ALG_PKMODE_COPY_NSZ_N_E): 561 case (OP_ALG_PKMODE_COPY_SSZ_A0_B0): 562 case (OP_ALG_PKMODE_COPY_SSZ_A0_B1): 563 case (OP_ALG_PKMODE_COPY_SSZ_A0_B2): 564 case (OP_ALG_PKMODE_COPY_SSZ_A0_B3): 565 case (OP_ALG_PKMODE_COPY_SSZ_A1_B0): 566 case (OP_ALG_PKMODE_COPY_SSZ_A1_B1): 567 case (OP_ALG_PKMODE_COPY_SSZ_A1_B2): 568 case (OP_ALG_PKMODE_COPY_SSZ_A1_B3): 569 case (OP_ALG_PKMODE_COPY_SSZ_A2_B0): 570 case (OP_ALG_PKMODE_COPY_SSZ_A2_B1): 571 case (OP_ALG_PKMODE_COPY_SSZ_A2_B2): 572 case (OP_ALG_PKMODE_COPY_SSZ_A2_B3): 573 case (OP_ALG_PKMODE_COPY_SSZ_A3_B0): 574 case (OP_ALG_PKMODE_COPY_SSZ_A3_B1): 575 case (OP_ALG_PKMODE_COPY_SSZ_A3_B2): 576 case (OP_ALG_PKMODE_COPY_SSZ_A3_B3): 577 case (OP_ALG_PKMODE_COPY_SSZ_B0_A0): 578 case (OP_ALG_PKMODE_COPY_SSZ_B0_A1): 579 case (OP_ALG_PKMODE_COPY_SSZ_B0_A2): 580 case (OP_ALG_PKMODE_COPY_SSZ_B0_A3): 581 case (OP_ALG_PKMODE_COPY_SSZ_B1_A0): 582 case (OP_ALG_PKMODE_COPY_SSZ_B1_A1): 583 case (OP_ALG_PKMODE_COPY_SSZ_B1_A2): 584 case (OP_ALG_PKMODE_COPY_SSZ_B1_A3): 585 case (OP_ALG_PKMODE_COPY_SSZ_B2_A0): 586 case (OP_ALG_PKMODE_COPY_SSZ_B2_A1): 587 case (OP_ALG_PKMODE_COPY_SSZ_B2_A2): 588 case (OP_ALG_PKMODE_COPY_SSZ_B2_A3): 589 case (OP_ALG_PKMODE_COPY_SSZ_B3_A0): 590 case (OP_ALG_PKMODE_COPY_SSZ_B3_A1): 591 case (OP_ALG_PKMODE_COPY_SSZ_B3_A2): 592 case (OP_ALG_PKMODE_COPY_SSZ_B3_A3): 593 case (OP_ALG_PKMODE_COPY_SSZ_A_E): 594 case (OP_ALG_PKMODE_COPY_SSZ_A_N): 595 case (OP_ALG_PKMODE_COPY_SSZ_B_E): 596 case (OP_ALG_PKMODE_COPY_SSZ_B_N): 597 case (OP_ALG_PKMODE_COPY_SSZ_N_A): 598 case (OP_ALG_PKMODE_COPY_SSZ_N_B): 599 case (OP_ALG_PKMODE_COPY_SSZ_N_E): 600 return 0; 601 } 602 603 return -EINVAL; 604 } 605 606 static inline int 607 rta_pkha_operation(struct program *program, uint32_t op_pkha) 608 { 609 uint32_t opcode = CMD_OPERATION | OP_TYPE_PK | OP_ALG_PK; 610 uint32_t pkha_func; 611 unsigned int start_pc = program->current_pc; 612 int ret = -EINVAL; 613 614 pkha_func = op_pkha & OP_ALG_PK_FUN_MASK; 615 616 switch (pkha_func) { 617 case (OP_ALG_PKMODE_CLEARMEM): 618 ret = __rta_pkha_clearmem(op_pkha); 619 if (ret < 0) { 620 pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n", 621 program->current_pc); 622 goto err; 623 } 624 break; 625 case (OP_ALG_PKMODE_MOD_ADD): 626 case (OP_ALG_PKMODE_MOD_SUB_AB): 627 case (OP_ALG_PKMODE_MOD_SUB_BA): 628 case (OP_ALG_PKMODE_MOD_MULT): 629 case (OP_ALG_PKMODE_MOD_EXPO): 630 case (OP_ALG_PKMODE_MOD_REDUCT): 631 case (OP_ALG_PKMODE_MOD_INV): 632 case (OP_ALG_PKMODE_MOD_MONT_CNST): 633 case (OP_ALG_PKMODE_MOD_CRT_CNST): 634 case (OP_ALG_PKMODE_MOD_GCD): 635 case (OP_ALG_PKMODE_MOD_PRIMALITY): 636 case (OP_ALG_PKMODE_MOD_SML_EXP): 637 case (OP_ALG_PKMODE_ECC_MOD_ADD): 638 case (OP_ALG_PKMODE_ECC_MOD_DBL): 639 case (OP_ALG_PKMODE_ECC_MOD_MUL): 640 ret = __rta_pkha_mod_arithmetic(op_pkha); 641 if (ret < 0) { 642 pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n", 643 program->current_pc); 644 goto err; 645 } 646 break; 647 case (OP_ALG_PKMODE_COPY_NSZ): 648 case (OP_ALG_PKMODE_COPY_SSZ): 649 ret = __rta_pkha_copymem(op_pkha); 650 if (ret < 0) { 651 pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n", 652 program->current_pc); 653 goto err; 654 } 655 break; 656 default: 657 pr_err("Invalid Operation Command\n"); 658 goto err; 659 } 660 661 opcode |= op_pkha; 662 663 __rta_out32(program, opcode); 664 program->current_instruction++; 665 return (int)start_pc; 666 667 err: 668 program->first_error_pc = start_pc; 669 program->current_instruction++; 670 return ret; 671 } 672 673 #endif /* __RTA_OPERATION_CMD_H__ */ 674