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