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