xref: /dpdk/drivers/common/dpaax/caamflib/rta/operation_cmd.h (revision 68a03efeed657e6e05f281479b33b51102797e15)
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