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