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