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