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