1 /* SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0)
2  *
3  * Copyright 2008-2016 Freescale Semiconductor Inc.
4  * Copyright 2016,2019 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 (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
__rta_alg_aai_des(uint16_t aai)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
__rta_alg_aai_md5(uint16_t aai)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
__rta_alg_aai_sha(uint16_t aai)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
__rta_alg_aai_rng(uint16_t aai)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
__rta_alg_aai_crc(uint16_t aai)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
__rta_alg_aai_kasumi(uint16_t aai)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
__rta_alg_aai_snow_f9(uint16_t aai)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
__rta_alg_aai_snow_f8(uint16_t aai)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
__rta_alg_aai_zuce(uint16_t aai)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
__rta_alg_aai_zuca(uint16_t aai)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
rta_operation(struct program * program,uint32_t cipher_algo,uint16_t aai,uint8_t algo_state,int icv_checking,int enc)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 			opcode |= cipher_algo | alg_table[i].class;
247 			/* nothing else to verify */
248 			if (alg_table[i].aai_func == NULL) {
249 				found = 1;
250 				break;
251 			}
252 
253 			aai &= OP_ALG_AAI_MASK;
254 
255 			ret = (*alg_table[i].aai_func)(aai);
256 			if (ret < 0) {
257 				pr_err("OPERATION: Bad AAI Type. SEC Program Line: %d\n",
258 				       program->current_pc);
259 				goto err;
260 			}
261 			opcode |= aai;
262 			found = 1;
263 			break;
264 		}
265 	}
266 	if (!found) {
267 		pr_err("OPERATION: Invalid Command. SEC Program Line: %d\n",
268 		       program->current_pc);
269 		ret = -EINVAL;
270 		goto err;
271 	}
272 
273 	switch (algo_state) {
274 	case OP_ALG_AS_UPDATE:
275 	case OP_ALG_AS_INIT:
276 	case OP_ALG_AS_FINALIZE:
277 	case OP_ALG_AS_INITFINAL:
278 		opcode |= algo_state;
279 		break;
280 	default:
281 		pr_err("Invalid Operation Command\n");
282 		ret = -EINVAL;
283 		goto err;
284 	}
285 
286 	switch (icv_checking) {
287 	case ICV_CHECK_DISABLE:
288 		/*
289 		 * opcode |= OP_ALG_ICV_OFF;
290 		 * OP_ALG_ICV_OFF is 0
291 		 */
292 		break;
293 	case ICV_CHECK_ENABLE:
294 		opcode |= OP_ALG_ICV_ON;
295 		break;
296 	default:
297 		pr_err("Invalid Operation Command\n");
298 		ret = -EINVAL;
299 		goto err;
300 	}
301 
302 	switch (enc) {
303 	case DIR_DEC:
304 		/*
305 		 * opcode |= OP_ALG_DECRYPT;
306 		 * OP_ALG_DECRYPT is 0
307 		 */
308 		break;
309 	case DIR_ENC:
310 		opcode |= OP_ALG_ENCRYPT;
311 		break;
312 	default:
313 		pr_err("Invalid Operation Command\n");
314 		ret = -EINVAL;
315 		goto err;
316 	}
317 
318 	__rta_out32(program, opcode);
319 	program->current_instruction++;
320 	return (int)start_pc;
321 
322  err:
323 	program->first_error_pc = start_pc;
324 	return ret;
325 }
326 
327 /*
328  * OPERATION PKHA routines
329  */
330 static inline int
__rta_pkha_clearmem(uint32_t pkha_op)331 __rta_pkha_clearmem(uint32_t pkha_op)
332 {
333 	switch (pkha_op) {
334 	case (OP_ALG_PKMODE_CLEARMEM_ALL):
335 	case (OP_ALG_PKMODE_CLEARMEM_ABE):
336 	case (OP_ALG_PKMODE_CLEARMEM_ABN):
337 	case (OP_ALG_PKMODE_CLEARMEM_AB):
338 	case (OP_ALG_PKMODE_CLEARMEM_AEN):
339 	case (OP_ALG_PKMODE_CLEARMEM_AE):
340 	case (OP_ALG_PKMODE_CLEARMEM_AN):
341 	case (OP_ALG_PKMODE_CLEARMEM_A):
342 	case (OP_ALG_PKMODE_CLEARMEM_BEN):
343 	case (OP_ALG_PKMODE_CLEARMEM_BE):
344 	case (OP_ALG_PKMODE_CLEARMEM_BN):
345 	case (OP_ALG_PKMODE_CLEARMEM_B):
346 	case (OP_ALG_PKMODE_CLEARMEM_EN):
347 	case (OP_ALG_PKMODE_CLEARMEM_N):
348 	case (OP_ALG_PKMODE_CLEARMEM_E):
349 		return 0;
350 	}
351 
352 	return -EINVAL;
353 }
354 
355 static inline int
__rta_pkha_mod_arithmetic(uint32_t pkha_op)356 __rta_pkha_mod_arithmetic(uint32_t pkha_op)
357 {
358 	pkha_op &= (uint32_t)~OP_ALG_PKMODE_OUT_A;
359 
360 	switch (pkha_op) {
361 	case (OP_ALG_PKMODE_MOD_ADD):
362 	case (OP_ALG_PKMODE_MOD_SUB_AB):
363 	case (OP_ALG_PKMODE_MOD_SUB_BA):
364 	case (OP_ALG_PKMODE_MOD_MULT):
365 	case (OP_ALG_PKMODE_MOD_MULT_IM):
366 	case (OP_ALG_PKMODE_MOD_MULT_IM_OM):
367 	case (OP_ALG_PKMODE_MOD_EXPO):
368 	case (OP_ALG_PKMODE_MOD_EXPO_TEQ):
369 	case (OP_ALG_PKMODE_MOD_EXPO_IM):
370 	case (OP_ALG_PKMODE_MOD_EXPO_IM_TEQ):
371 	case (OP_ALG_PKMODE_MOD_REDUCT):
372 	case (OP_ALG_PKMODE_MOD_INV):
373 	case (OP_ALG_PKMODE_MOD_MONT_CNST):
374 	case (OP_ALG_PKMODE_MOD_CRT_CNST):
375 	case (OP_ALG_PKMODE_MOD_GCD):
376 	case (OP_ALG_PKMODE_MOD_PRIMALITY):
377 	case (OP_ALG_PKMODE_MOD_SML_EXP):
378 	case (OP_ALG_PKMODE_F2M_ADD):
379 	case (OP_ALG_PKMODE_F2M_MUL):
380 	case (OP_ALG_PKMODE_F2M_MUL_IM):
381 	case (OP_ALG_PKMODE_F2M_MUL_IM_OM):
382 	case (OP_ALG_PKMODE_F2M_EXP):
383 	case (OP_ALG_PKMODE_F2M_EXP_TEQ):
384 	case (OP_ALG_PKMODE_F2M_AMODN):
385 	case (OP_ALG_PKMODE_F2M_INV):
386 	case (OP_ALG_PKMODE_F2M_R2):
387 	case (OP_ALG_PKMODE_F2M_GCD):
388 	case (OP_ALG_PKMODE_F2M_SML_EXP):
389 	case (OP_ALG_PKMODE_ECC_F2M_ADD):
390 	case (OP_ALG_PKMODE_ECC_F2M_ADD_IM_OM_PROJ):
391 	case (OP_ALG_PKMODE_ECC_F2M_DBL):
392 	case (OP_ALG_PKMODE_ECC_F2M_DBL_IM_OM_PROJ):
393 	case (OP_ALG_PKMODE_ECC_F2M_MUL):
394 	case (OP_ALG_PKMODE_ECC_F2M_MUL_TEQ):
395 	case (OP_ALG_PKMODE_ECC_F2M_MUL_R2):
396 	case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_TEQ):
397 	case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_PROJ):
398 	case (OP_ALG_PKMODE_ECC_F2M_MUL_R2_PROJ_TEQ):
399 	case (OP_ALG_PKMODE_ECC_MOD_ADD):
400 	case (OP_ALG_PKMODE_ECC_MOD_ADD_IM_OM_PROJ):
401 	case (OP_ALG_PKMODE_ECC_MOD_DBL):
402 	case (OP_ALG_PKMODE_ECC_MOD_DBL_IM_OM_PROJ):
403 	case (OP_ALG_PKMODE_ECC_MOD_MUL):
404 	case (OP_ALG_PKMODE_ECC_MOD_MUL_TEQ):
405 	case (OP_ALG_PKMODE_ECC_MOD_MUL_R2):
406 	case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_TEQ):
407 	case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_PROJ):
408 	case (OP_ALG_PKMODE_ECC_MOD_MUL_R2_PROJ_TEQ):
409 		return 0;
410 	}
411 
412 	return -EINVAL;
413 }
414 
415 static inline int
__rta_pkha_copymem(uint32_t pkha_op)416 __rta_pkha_copymem(uint32_t pkha_op)
417 {
418 	switch (pkha_op) {
419 	case (OP_ALG_PKMODE_COPY_NSZ_A0_B0):
420 	case (OP_ALG_PKMODE_COPY_NSZ_A0_B1):
421 	case (OP_ALG_PKMODE_COPY_NSZ_A0_B2):
422 	case (OP_ALG_PKMODE_COPY_NSZ_A0_B3):
423 	case (OP_ALG_PKMODE_COPY_NSZ_A1_B0):
424 	case (OP_ALG_PKMODE_COPY_NSZ_A1_B1):
425 	case (OP_ALG_PKMODE_COPY_NSZ_A1_B2):
426 	case (OP_ALG_PKMODE_COPY_NSZ_A1_B3):
427 	case (OP_ALG_PKMODE_COPY_NSZ_A2_B0):
428 	case (OP_ALG_PKMODE_COPY_NSZ_A2_B1):
429 	case (OP_ALG_PKMODE_COPY_NSZ_A2_B2):
430 	case (OP_ALG_PKMODE_COPY_NSZ_A2_B3):
431 	case (OP_ALG_PKMODE_COPY_NSZ_A3_B0):
432 	case (OP_ALG_PKMODE_COPY_NSZ_A3_B1):
433 	case (OP_ALG_PKMODE_COPY_NSZ_A3_B2):
434 	case (OP_ALG_PKMODE_COPY_NSZ_A3_B3):
435 	case (OP_ALG_PKMODE_COPY_NSZ_B0_A0):
436 	case (OP_ALG_PKMODE_COPY_NSZ_B0_A1):
437 	case (OP_ALG_PKMODE_COPY_NSZ_B0_A2):
438 	case (OP_ALG_PKMODE_COPY_NSZ_B0_A3):
439 	case (OP_ALG_PKMODE_COPY_NSZ_B1_A0):
440 	case (OP_ALG_PKMODE_COPY_NSZ_B1_A1):
441 	case (OP_ALG_PKMODE_COPY_NSZ_B1_A2):
442 	case (OP_ALG_PKMODE_COPY_NSZ_B1_A3):
443 	case (OP_ALG_PKMODE_COPY_NSZ_B2_A0):
444 	case (OP_ALG_PKMODE_COPY_NSZ_B2_A1):
445 	case (OP_ALG_PKMODE_COPY_NSZ_B2_A2):
446 	case (OP_ALG_PKMODE_COPY_NSZ_B2_A3):
447 	case (OP_ALG_PKMODE_COPY_NSZ_B3_A0):
448 	case (OP_ALG_PKMODE_COPY_NSZ_B3_A1):
449 	case (OP_ALG_PKMODE_COPY_NSZ_B3_A2):
450 	case (OP_ALG_PKMODE_COPY_NSZ_B3_A3):
451 	case (OP_ALG_PKMODE_COPY_NSZ_A_E):
452 	case (OP_ALG_PKMODE_COPY_NSZ_A_N):
453 	case (OP_ALG_PKMODE_COPY_NSZ_B_E):
454 	case (OP_ALG_PKMODE_COPY_NSZ_B_N):
455 	case (OP_ALG_PKMODE_COPY_NSZ_N_A):
456 	case (OP_ALG_PKMODE_COPY_NSZ_N_B):
457 	case (OP_ALG_PKMODE_COPY_NSZ_N_E):
458 	case (OP_ALG_PKMODE_COPY_SSZ_A0_B0):
459 	case (OP_ALG_PKMODE_COPY_SSZ_A0_B1):
460 	case (OP_ALG_PKMODE_COPY_SSZ_A0_B2):
461 	case (OP_ALG_PKMODE_COPY_SSZ_A0_B3):
462 	case (OP_ALG_PKMODE_COPY_SSZ_A1_B0):
463 	case (OP_ALG_PKMODE_COPY_SSZ_A1_B1):
464 	case (OP_ALG_PKMODE_COPY_SSZ_A1_B2):
465 	case (OP_ALG_PKMODE_COPY_SSZ_A1_B3):
466 	case (OP_ALG_PKMODE_COPY_SSZ_A2_B0):
467 	case (OP_ALG_PKMODE_COPY_SSZ_A2_B1):
468 	case (OP_ALG_PKMODE_COPY_SSZ_A2_B2):
469 	case (OP_ALG_PKMODE_COPY_SSZ_A2_B3):
470 	case (OP_ALG_PKMODE_COPY_SSZ_A3_B0):
471 	case (OP_ALG_PKMODE_COPY_SSZ_A3_B1):
472 	case (OP_ALG_PKMODE_COPY_SSZ_A3_B2):
473 	case (OP_ALG_PKMODE_COPY_SSZ_A3_B3):
474 	case (OP_ALG_PKMODE_COPY_SSZ_B0_A0):
475 	case (OP_ALG_PKMODE_COPY_SSZ_B0_A1):
476 	case (OP_ALG_PKMODE_COPY_SSZ_B0_A2):
477 	case (OP_ALG_PKMODE_COPY_SSZ_B0_A3):
478 	case (OP_ALG_PKMODE_COPY_SSZ_B1_A0):
479 	case (OP_ALG_PKMODE_COPY_SSZ_B1_A1):
480 	case (OP_ALG_PKMODE_COPY_SSZ_B1_A2):
481 	case (OP_ALG_PKMODE_COPY_SSZ_B1_A3):
482 	case (OP_ALG_PKMODE_COPY_SSZ_B2_A0):
483 	case (OP_ALG_PKMODE_COPY_SSZ_B2_A1):
484 	case (OP_ALG_PKMODE_COPY_SSZ_B2_A2):
485 	case (OP_ALG_PKMODE_COPY_SSZ_B2_A3):
486 	case (OP_ALG_PKMODE_COPY_SSZ_B3_A0):
487 	case (OP_ALG_PKMODE_COPY_SSZ_B3_A1):
488 	case (OP_ALG_PKMODE_COPY_SSZ_B3_A2):
489 	case (OP_ALG_PKMODE_COPY_SSZ_B3_A3):
490 	case (OP_ALG_PKMODE_COPY_SSZ_A_E):
491 	case (OP_ALG_PKMODE_COPY_SSZ_A_N):
492 	case (OP_ALG_PKMODE_COPY_SSZ_B_E):
493 	case (OP_ALG_PKMODE_COPY_SSZ_B_N):
494 	case (OP_ALG_PKMODE_COPY_SSZ_N_A):
495 	case (OP_ALG_PKMODE_COPY_SSZ_N_B):
496 	case (OP_ALG_PKMODE_COPY_SSZ_N_E):
497 		return 0;
498 	}
499 
500 	return -EINVAL;
501 }
502 
503 static inline int
rta_pkha_operation(struct program * program,uint32_t op_pkha)504 rta_pkha_operation(struct program *program, uint32_t op_pkha)
505 {
506 	uint32_t opcode = CMD_OPERATION | OP_TYPE_PK | OP_ALG_PK;
507 	uint32_t pkha_func;
508 	unsigned int start_pc = program->current_pc;
509 	int ret = -EINVAL;
510 
511 	pkha_func = op_pkha & OP_ALG_PK_FUN_MASK;
512 
513 	switch (pkha_func) {
514 	case (OP_ALG_PKMODE_CLEARMEM):
515 		ret = __rta_pkha_clearmem(op_pkha);
516 		if (ret < 0) {
517 			pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n",
518 			       program->current_pc);
519 			goto err;
520 		}
521 		break;
522 	case (OP_ALG_PKMODE_MOD_ADD):
523 	case (OP_ALG_PKMODE_MOD_SUB_AB):
524 	case (OP_ALG_PKMODE_MOD_SUB_BA):
525 	case (OP_ALG_PKMODE_MOD_MULT):
526 	case (OP_ALG_PKMODE_MOD_EXPO):
527 	case (OP_ALG_PKMODE_MOD_REDUCT):
528 	case (OP_ALG_PKMODE_MOD_INV):
529 	case (OP_ALG_PKMODE_MOD_MONT_CNST):
530 	case (OP_ALG_PKMODE_MOD_CRT_CNST):
531 	case (OP_ALG_PKMODE_MOD_GCD):
532 	case (OP_ALG_PKMODE_MOD_PRIMALITY):
533 	case (OP_ALG_PKMODE_MOD_SML_EXP):
534 	case (OP_ALG_PKMODE_ECC_MOD_ADD):
535 	case (OP_ALG_PKMODE_ECC_MOD_DBL):
536 	case (OP_ALG_PKMODE_ECC_MOD_MUL):
537 		ret = __rta_pkha_mod_arithmetic(op_pkha);
538 		if (ret < 0) {
539 			pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n",
540 			       program->current_pc);
541 			goto err;
542 		}
543 		break;
544 	case (OP_ALG_PKMODE_COPY_NSZ):
545 	case (OP_ALG_PKMODE_COPY_SSZ):
546 		ret = __rta_pkha_copymem(op_pkha);
547 		if (ret < 0) {
548 			pr_err("OPERATION PKHA: Type not supported. SEC Program Line: %d\n",
549 			       program->current_pc);
550 			goto err;
551 		}
552 		break;
553 	default:
554 		pr_err("Invalid Operation Command\n");
555 		goto err;
556 	}
557 
558 	opcode |= op_pkha;
559 
560 	__rta_out32(program, opcode);
561 	program->current_instruction++;
562 	return (int)start_pc;
563 
564  err:
565 	program->first_error_pc = start_pc;
566 	program->current_instruction++;
567 	return ret;
568 }
569 
570 #endif /* __RTA_OPERATION_CMD_H__ */
571