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