1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 
8 #ifndef PKA_H
9 #define PKA_H
10 
11 #include "cc_pal_types.h"
12 #include "cc_error.h"
13 #include "pka_hw_defs.h"
14 #include "cc_pka_defs_hw.h"
15 #include "pki_dbg.h"
16 
17 
18 #ifdef __cplusplus
19 extern "C"
20 {
21 #endif
22 
23 
24 /* values for defining, that PKA entry is not in use */
25 #define PKA_SIZE_ENTRY_NOT_USED  0xFFFFFFFF
26 #define PKA_ADDRESS_ENTRY_NOT_USED  0xFFC
27 
28 /* define result discard value */
29 #define RES_DISCARD  0x3F
30 
31 
32 #define SWAP_INT8(x,y)  { \
33    uint32_t  temp; \
34    temp = (x); x = (y); y = temp; \
35 }
36 
37 
38 
39 /* if you want to execute operation using function defined in pki_dbg.c,
40  then change the define of PKA_EXEC_OP_DEBUG to 1, else define it as empty.
41  Make sure the library is compiled with flag DEBUG=1, so pki_dbg.c exists in library */
42 #define PKA_EXEC_OP_DEBUG 0
43 #if (PKA_EXEC_OP_DEBUG  && defined PKA_DEBUG && defined DEBUG)
44     #define PKA_EXEC_OPERATION PkiDbgExecOperation
45 #else   // not debug mode
46     #define PKA_EXEC_OPERATION(Opcode,lenId,isAImmed,OpA,isBImmed,OpB,ResDiscard,Res,Tag) { \
47         uint32_t fullOpCode; \
48         fullOpCode = PKA_SET_FULL_OPCODE((Opcode),(lenId),(isAImmed),(OpA),(isBImmed),(OpB),(ResDiscard),(Res),(Tag)); \
49         PKA_WAIT_ON_PKA_PIPE_READY(); \
50         CC_HAL_WRITE_REGISTER(CC_REG_OFFSET(CRY_KERNEL, OPCODE), fullOpCode); \
51     }
52 #endif
53 
54 /*************************************************************************/
55 /* Macros for calling PKA operations (names according to operation issue */
56 /*************************************************************************/
57 
58 /*----------------------------------*/
59 /*   1.  ADD - SUBTRACT operations  */
60 /*----------------------------------*/
61 /*  Add:   Res =  OpA + OpB  */
62 #define   PKA_ADD(lenId, Res, OpA, OpB)   \
63             PKA_EXEC_OPERATION( PKA_OPCODE_ID_ADD,(lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
64 /*  AddIm:  Res =  OpA + OpBIm  */
65 #define   PKA_ADD_IM(lenId, Res, OpA, OpBIm)   \
66             PKA_EXEC_OPERATION( PKA_OPCODE_ID_ADD,(lenId), 0, (OpA), 1, (OpBIm), 0, (Res), 0 )
67 /*  Sub:  Res =  OpA - OpB  */
68 #define   PKA_SUB(lenId, Res, OpA, OpB)   \
69             PKA_EXEC_OPERATION( PKA_OPCODE_ID_SUB,(lenId),0, (OpA), 0, (OpB), 0, (Res), 0 )
70 /*  SubIm:  Res =  OpA - OpBIm  */
71 #define   PKA_SUB_IM(lenId, Res, OpA, OpBIm)   \
72             PKA_EXEC_OPERATION( PKA_OPCODE_ID_SUB,(lenId), 0, (OpA), 1, (OpBIm), 0, (Res), 0 )
73 /*  Neg:  Res =  0 - OpB  */
74 #define   PKA_NEG(lenId, Res, OpB)   \
75             PKA_EXEC_OPERATION( PKA_OPCODE_ID_SUB, (lenId), 1, 0, 0, (OpB), 0, (Res), 0 )
76 /*  ModAdd:  Res =  (OpA + OpB) mod N  */
77 #define   PKA_MOD_ADD(lenId, Res, OpA, OpB)   \
78             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODADD, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
79 /*  ModAddIm:  Res =  (OpA + OpBIm) mod N  */
80 #define   PKA_MOD_ADD_IM(lenId, Res, OpA, OpBIm)   \
81             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODADD, (lenId), 0, (OpA), 1, (OpBIm), 0, (Res), 0 )
82 /*  ModSub:  Res =  (OpA - OpB) mod N  */
83 #define   PKA_MOD_SUB(lenId, Res, OpA, OpB)   \
84              PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODSUB, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
85 /*  ModSubIm:  Res =  (OpA - OpBIm) mod N  */
86 #define   PKA_MOD_SUB_IM(lenId, Res, OpA, OpBIm)   \
87             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODSUB, (lenId), 0, (OpA), 1, (OpBIm), 0, (Res), 0 )
88 /*  ModNeg:  Res =  (0 - OpB) mod N  */
89 #define   PKA_MOD_NEG(lenId, Res, OpB)   \
90             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODSUB, (lenId), 1, 0, 0, (OpB), 0, (Res), 0 )
91 
92 
93 /*----------------------------------*/
94 /*   2.  Logical   operations       */
95 /*----------------------------------*/
96 
97 /*  AND:  Res =  OpA & OpB  */
98 #define   PKA_AND(lenId, Res, OpA, OpB)   \
99             PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 0, (OpB), 0, (Res) , 0 )
100 /*  AndIm:  Res =  OpA & OpB  */
101 #define   PKA_AND_IM(lenId, Res, OpA, OpB)   \
102             PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 1, (OpB), 0, (Res) , 0 )
103 /*  Tst0:  OpA & 0x1 -  tests the bit 0 of operand A. If bit0 = 0, then ZeroOfStatus = 1, else 0  */
104 #define   PKA_TEST_BIT0(lenId, OpA)   \
105             PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 1, 0x01, 1, RES_DISCARD , 0 )
106 /*  TstBit:  OpA & (1<<i) -  tests the bit i of operand A. If biti = 0, then ZeroOfStatus = 1, else 0  */
107 #define   PKA_TEST_BIT(lenId, OpA, i)   \
108             PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 1, 0x01<<(i), 1, RES_DISCARD , 0 )
109 /*  Clr0:  Res =  OpA & (-2)  - clears the bit 0 of operand A.  Note:  -2 = 0x1E  for 5-bit size */
110 #define   PKA_CLEAR_BIT0(lenId, Res, OpA)   \
111             PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 1, 0x1E, 0, (Res), 0 )
112 /*  Clr:  Res =  OpA & 0  - clears the operand A.  */
113 #define   PKA_CLEAR(lenId, OpA)   \
114             PKA_EXEC_OPERATION( PKA_OPCODE_ID_AND, (lenId), 0, (OpA), 1, 0x00, 0, (OpA), 0 )
115 /*  Clear:  for full clearing the actual register opA, this macro calls Clr operation twice.  */
116 #define   PKA_2CLEAR(lenId, OpA)   \
117             PKA_CLEAR(lenId, OpA);  \
118             PKA_CLEAR(lenId, OpA)
119 /*  OR:  Res =  OpA || OpB  */
120 #define   PKA_OR(lenId, Res, OpA, OpB)   \
121             PKA_EXEC_OPERATION( PKA_OPCODE_ID_OR, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
122 /*  OrIm:  Res =  OpA || OpB  */
123 #define   PKA_OR_IM(lenId, Res, OpA, OpB)   \
124             PKA_EXEC_OPERATION( PKA_OPCODE_ID_OR, (lenId), 0, (OpA), 1, (OpB), 0, (Res), 0 )
125 /*  Copy:  OpDest =  OpSrc || 0  */
126 #define   PKA_COPY(lenId, OpDest, OpSrc)   \
127             PKA_EXEC_OPERATION( PKA_OPCODE_ID_OR, (lenId), 0, (OpSrc), 1, 0x00, 0, (OpDest), 0 )
128 /*  Set0:  Res =  OpA || 1  : set bit0 = 1, other bits are not changed */
129 #define   PKA_SET_BIT0(lenId, Res, OpA)   \
130             PKA_EXEC_OPERATION( PKA_OPCODE_ID_OR, (lenId), 0, (OpA), 1, 0x01, 0, (Res), 0 )
131 /*  Xor:  Res =  OpA ^ OpB  */
132 #define   PKA_XOR(lenId, Res, OpA, OpB)   \
133             PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
134 /*  XorIm:  Res =  OpA ^ OpB  */
135 #define   PKA_XOR_IM(lenId, Res, OpA, OpB)   \
136             PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 1, (OpB), 0, (Res), 0 )
137 /*  Flip0:  OpA =  OpA || 1  - inverts the bit 0 of operand A  */
138 #define   PKA_FLIP_BIT0(lenId, Res, OpA)   \
139             PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 1, 0x01, 0, (Res), 0 )
140 /*  Invert:  Res =  OpA ^ 0xFFF.FF  :  inverts all bits of OpA .
141                     Note: 0xFFFFF =  0x1F for 5 bits size of second operand */
142 #define   PKA_INVERT_BITS(lenId, Res, OpA)   \
143             PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 1, 0x1F, 0, (Res), 0 )
144 /*  Compare:  OpA ^ OpB . Rsult of compare in ZeroBitOfStatus:  If OpA == OpB then Z = 1 */
145 #define   PKA_COMPARE(lenId, OpA, OpB)   \
146             PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 0, (OpB), 1, (0), 0 )
147 /*  CompareImmediate:  OpA ^ OpB . Rsult of compare in ZeroBitOfStatus:  If OpA == OpB then status Z = 1 */
148 #define   PKA_COMPARE_IM(lenId, OpA, OpBim)   \
149             PKA_EXEC_OPERATION( PKA_OPCODE_ID_XOR, (lenId), 0, (OpA), 1, (OpBim), 1, (0), 0 )
150 
151 
152 /*----------------------------------*/
153 /*   3.  SHIFT    operations  - S <= 31      */
154 /*----------------------------------*/
155 
156 /*  SHR0:  Res =  OpA >> (S+1) :   shifts right operand A by S+1 bits, insert 0 to left most bits */
157 #define   PKA_SHR_FILL0(lenId, Res, OpA, S)   \
158             PKA_EXEC_OPERATION( PKA_OPCODE_ID_SHR0, (lenId), 0, (OpA), 0, (S), 0, (Res), 0 )
159 /*  SHR1:  Res =  OpA >> (S+1) :   shifts right operand A by S+1 bits, insert 1 to left most bits */
160 #define   PKA_SHR_FILL1(lenId, OpA, S, Res)   \
161             PKA_EXEC_OPERATION( PKA_OPCODE_ID_SHR1, (lenId), 0, (OpA), 0, (S), 0, (Res), 0 )
162 /*  SHL0:  Res =  OpA << (S+1) :   shifts left operand A by S+1 bits, insert 0 to right most bits */
163 #define   PKA_SHL_FILL0(lenId, Res, OpA, S)   \
164             PKA_EXEC_OPERATION( PKA_OPCODE_ID_SHL0, (lenId), 0, (OpA), 0, (S), 0, (Res), 0 )
165 /*  SHL1:  Res =  OpA << (S+1) :   shifts left operand A by S+1 bits, insert 1 to right most bits */
166 #define   PKA_SHL_FILL1(lenId, OpA, S, Res)   \
167             PKA_EXEC_OPERATION( PKA_OPCODE_ID_SHL1, (lenId), 0, (OpA), 0, (S), 0, (Res), 0 )
168 
169 
170 /*-----------------------------------------------------*/
171 /*   2.  Multiplication and other   operations         */
172 /*       Note:  See notes to PKA_ExecOperation */
173 /*-----------------------------------------------------*/
174 
175 /*  RMul:  Res =  LowHalfOf(OpA * OpB), where size of operands and result is equaled to operation
176            size, defined by lenId. Note: for receiving full result, the lenId must be set according
177            to (sizeA + sizeB) and leading not significant bits of operands must be zeroed */
178 #define   PKA_MUL_LOW(lenId, Res, OpA, OpB)   \
179              PKA_EXEC_OPERATION( PKA_OPCODE_ID_MULLOW, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
180 /*  HMul:  Res =  HighHalfOf(OpA * OpB) + one high word of low half of (OpA * OpB), where size of
181            operands is equaled to operation size, defined by lenId. Note: Size of operation result
182            is by one word large, than operation size */
183 #define   PKA_MUL_HIGH(lenId, Res, OpA, OpB)   \
184              PKA_EXEC_OPERATION( PKA_OPCODE_ID_MULHIGH, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
185 /*  ModMul:  Res =  OpA * OpB  mod N - modular multiplication */
186 #define   PKA_MOD_MUL(lenId, Res, OpA, OpB)   \
187              PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODMUL, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
188 /*  ModMulN:  Res =  OpA * OpB  mod N - modular multiplication (final reduction is omitted)*
189 *   up to PKA_EXTRA_BITS extra bits                               */
190 #define   PKA_MOD_MUL_NFR(lenId, Res, OpA, OpB)   \
191              PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODMULN, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
192 /*  ModMulAcc:  Res =  OpA * OpB + OpC mod N - modular multiplication and     *
193 *   adding, result reduced                                */
194 #define   PKA_MOD_MUL_ACC(lenId, Res, OpA, OpB, OpC)   \
195              PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODMLAC, (lenId), 0, (OpA), 0, (OpB), 0, (Res), (OpC) )
196 /*  ModMulAccN:  Res =  OpA * OpB + OpC mod N - modular multiplication and    *
197 *   acdding (final reduction is omitted) -  up to PKA_EXTRA_BITS extra bits                       */
198 #define   PKA_MOD_MUL_ACC_NFR(lenId, Res, OpA, OpB, OpC)   \
199              PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODMLACNR, (lenId), 0, (OpA), 0, (OpB), 0, (Res), (OpC) )
200 /*  ModExp:  Res =  OpA ** OpB  mod N - modular exponentiation */
201 #define   PKA_MOD_EXP(lenId, Res, OpA, OpB)   \
202              PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODEXP, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
203 /*  Divide:  Res =  OpA / OpB , OpA = OpA mod OpB - division,  */
204 #define   PKA_DIV(lenId, Res, OpA, OpB) \
205             PKA_EXEC_OPERATION( PKA_OPCODE_ID_DIVISION, (lenId), 0, (OpA), 0, (OpB), 0, (Res), 0 )
206 /*  ModInv:  Modular inversion: calculates   Res = 1/OpB mod N  */
207 #define   PKA_MOD_INV(lenId, Res, OpB)   \
208             PKA_EXEC_OPERATION( PKA_OPCODE_ID_MODINV, (lenId), 1,1, 0,(OpB), 0,(Res), 0 )
209 /* Modular reduction: Res = OpB mod B  by subtract the modulus B     *
210 *   times, while Res > B. Counter C should be set in the Tag bits of Status   */
211 #define   PKA_REDUCE(lenId, Res, OpA)   \
212             PKA_EXEC_OPERATION( PKA_OPCODE_ID_REDUCTION, (lenId), 0, (OpA), 0, 0/*opB not need*/, 0, (Res), 0/*Tag*/ )
213 
214 
215 /*************************************************
216   **************  second Level macros ************
217 **************************************************/
218 
219  /* mod inversion using exponentiation, used when 'a' can be even number, but *
220  *  runs at constant time                                                     */
221 #define PKA_MOD_INV_W_EXP(res,a,nm2)    {\
222     PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS,(nm2), 0/*n*/, 2); \
223     PKA_MOD_EXP(LEN_ID_N_BITS,(res),(a),(nm2)); \
224 }
225 
226 #define PKA_SET_VAL(a,v) {\
227     PKA_AND_IM(LEN_ID_N_PKA_REG_BITS,a,a,0); \
228     PKA_OR_IM( LEN_ID_N_PKA_REG_BITS,a,a,v); \
229 }
230 
231 #define PKA_COMPARE_STATUS(lenId, a, b, stat) {\
232     PKA_COMPARE(lenId,a,b); \
233     PKA_GET_STATUS_ALU_OUT_ZERO(stat);\
234 }
235 
236 #define PKA_COMPARE_IM_STATUS(lenId, a, b,stat)  {\
237     PKA_COMPARE_IM(lenId,a,b); \
238     PKA_GET_STATUS_ALU_OUT_ZERO(stat);\
239 }
240 
241 #define PKA_READ_BIT0(lenId,reg,bitVal) {\
242     PKA_TEST_BIT0(lenId,reg); \
243     PKA_GET_STATUS_ALU_OUT_ZERO(bitVal); \
244     (bitVal) = !(bitVal); \
245 }
246 
247 /*uint32 b - bit i value, i-num. of LS bit, i <= 31*/
248 #define PKA_READ_BIT(bitVal,reg,i) {\
249     PKA_TEST_BIT(1/*lenId*/,reg,(i),0); \
250     PKA_GET_STATUS_ALU_OUT_ZERO((bitVal)); \
251     (bitVal) = !(bitVal); \
252 }
253 
254 #define PKA_READ_WORD_FROM_REG(val,i,virtReg) {\
255     uint32_t addr; \
256     PKA_GET_REG_ADDRESS(virtReg, addr);\
257     PKA_HW_READ_VALUE_FROM_PKA_MEM(addr+(i), val); \
258 }
259 
260 #define PKA_WRITE_WORD_TO_REG(Val,i,VirtReg) {\
261     uint32_t addr;\
262     PKA_GET_REG_ADDRESS((VirtReg),addr);\
263     PKA_HW_LOAD_VALUE_TO_PKA_MEM(addr+(i),(Val));\
264 }
265 
266 CCError_t PkaExecFullModInv(int8_t         OpB,
267                               int8_t         Res,
268                               int8_t         rT0,
269                               int8_t         rT1,
270                               int8_t         rT2,
271                               int8_t         rT3 );
272 
273 uint8_t  PkaGetBitFromPkaReg(uint32_t   rX,
274                  uint32_t   lenId,
275                  int32_t    i,
276                  uint32_t   rT);
277 
278 
279 void  PkaModDivideBy2(uint32_t    lenId,
280               uint32_t    rX,
281               uint32_t    rN,
282               uint32_t    rRes);
283 
284 
285 CCError_t PkaInitAndMutexLock(uint32_t  sizeInBits,
286                 uint32_t *pkaRegCount);
287 
288 void PkaFinishAndMutexUnlock(uint32_t pkaRegCount);
289 
290 void PkaSetLenIds(uint32_t  sizeInBits,
291         uint32_t lenId);
292 
293 void PkaSetRegsSizesTab(uint32_t    opSizeInBits,
294              int32_t     regSizeInPkaWords);
295 
296 
297 CCError_t PkaInitPka(uint32_t   opSizeInBits,
298             uint32_t   regSizeInPkaWords,
299             uint32_t   *pRegsCount);
300 
301 #define PKA_INIT_PKA_DEFAULT(opSizeInBits) \
302         PkaInitPka((opSizeInBits), 0 /*sizeInWords*/, NULL/*(pRegsCount)*/)
303 
304 
305 void PkaFinishPka(void);
306 
307 
308 CCError_t  PkaCalcNpIntoPkaReg(uint32_t lenId,
309                 uint32_t  sizeNbits,
310                 int8_t regN,
311                 int8_t regNp,
312                 int8_t regTemp1,
313                 int8_t regTempN);
314 
315 void PkaClearBlockOfRegs(uint32_t  firstReg,
316                          int32_t   countOfRegs,
317                          uint32_t  lenId);
318 
319 void PkaClearPkaRegWords(uint32_t    dstReg,
320               uint32_t    sizeWords);
321 
322 void PkaCopyByteBuffIntoPkaReg(uint32_t    dstReg,
323                  uint32_t    lenId,
324                  const uint8_t  *src_ptr,
325                  uint32_t    size);
326 
327 void PkaCopyBeByteBuffIntoPkaReg(uint32_t    dstReg,
328                  uint32_t    lenId,
329                  const uint8_t  *src_ptr,
330                  uint32_t    sizeWords);
331 
332 void PkaCopyDataIntoPkaReg(uint32_t    dstReg,
333                  uint32_t    lenId,
334                  const uint32_t  *src_ptr,
335                  uint32_t    sizeWords);
336 
337 void PkaCopyPkaRegIntoBeByteBuff(uint8_t *dst_ptr,
338                   uint32_t  sizeWords,
339                   uint32_t  srcReg);
340 
341 void PkaCopyDataFromPkaReg( uint32_t *dst_ptr,
342                   uint32_t  sizeWords,
343                   uint32_t  srcReg);
344 
345 uint32_t PkaGetRegEffectiveSizeInBits(uint32_t  reg);
346 
347 bool PkaIsRegModEqual(uint32_t reg1, uint32_t reg2, uint32_t regTmp1, uint32_t regTmp2);
348 
349 
350 uint32_t  PkaGetNextMsBit(uint32_t r, int32_t i, uint32_t *pW, uint32_t *pIsNew);
351 
352 
353 uint32_t  PkaGet2MsBits(uint32_t r, int32_t i, uint32_t *pW, uint32_t *pIsNew);
354 
355 #ifdef __cplusplus
356 }
357 #endif
358 
359 #endif
360