1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #define CC_PAL_LOG_CUR_COMPONENT HOST_LOG_MASK_SECURE_BOOT
8
9 #include "rsa_pki_pka.h"
10 #include "rsa_bsv.h"
11 #include "secureboot_stage_defs.h"
12
13
14 /************************ Defines ******************************/
15
16 /************************ Enums ********************************/
17
18 /************************ Typedefs ****************************/
19
20 /************************ Structs ******************************/
21
22 /************************ Public Variables **********************/
23 /* SRAM address used for the PKA */
24 const uint32_t g_SramPkaAddr = 0;
25
26 /************************ Public Functions ******************************/
27
28 #ifdef PKA_DEBUG
29 uint8_t tempRes[268];
30 #endif
31
32 /* ***************************************************************************** */
33 /* ********* RSA PKI PKA initialisation functions and macros ********* */
34 /* ***************************************************************************** */
35
36 /*********** PkaSetRegsSizesTab function **********************/
37 /**
38 * @brief This function initializes the PKA registers sizes table.
39 *
40 * The function sets sizes table as follows:
41 * - tab[0] = MaxSizeBits; //maximal size, usually this is exact modulus size in bits
42 * - tab[1] = Extended size with extra bits, aligned to big words.
43 * - other entrie,
44 uint32_t Xs = PKA_SIZE_ENTRY_NOT_USED, means - not used.
45 *
46 * @param[in] opSizeInBits - Size of PKA operations (modulus) in bits. The value must be in interval
47 * from defined Min. to Max. size bits.
48 * @param[in] regSizeInPkaWords - Sise of registers in PKA big words (e.g. 128-bit words).
49 *
50 * @return - no return value
51 *
52 */
RSA_PKA_SetRegsSizesTab(uint32_t opSizeInBits,int32_t regSizeInPkaWords,unsigned long virtualHwBaseAddr)53 void RSA_PKA_SetRegsSizesTab( uint32_t opSizeInBits,
54 int32_t regSizeInPkaWords,
55 unsigned long virtualHwBaseAddr)
56 {
57 /* LOCAL DECLARATIONS */
58
59 uint32_t i;
60
61 /* FUNCTION LOGIC */
62
63 /* Set exact op. size */
64 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, PKA_L0), opSizeInBits);
65 /* Set register size (with extra bits) aligned to PKA big words */
66 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, PKA_L0) + 4,
67 regSizeInPkaWords*RSA_PKA_BIG_WORD_SIZE_IN_BITS);
68
69 /* remaining entries set to PKA_SIZE_ENTRY_NOT_USED for debugging goals */
70 for (i = 2; i < RSA_PKA_MAX_COUNT_OF_REGS_SIZES; i++) {
71 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, PKA_L0) + 4*i, PKA_SIZE_ENTRY_NOT_USED);
72 }
73
74 return;
75
76 } /* END of the finction PkaSetRegsSizesTab */
77
78
79 /*********** PkaSetRegsMapTab function **********************/
80 /**
81 * @brief This function initializes the PKA registers sizes table.
82 *
83 * The function checks input parameters and sets the physical memory registers mapping-table
84 * according to parameters, passed by the user:
85 * - start address of register 0 is the start address of PKA data registers memory
86 * PKA_SRAM_REGS_MEM_OFFSET_WORDS (defined in pka_hw_defs.h file);
87 * - special registers are set as follows: N=0,NP=1,T0=30,T1=31;
88 * - all registers have the same size, equalled to given size;
89 *
90 * @param[in] countOfRegs - The count of registeres, requirred by the user.
91 * @param[in] regSizeInPkaWords - Sise of registers in PKA big words (e.g. 128-bit words).
92 * @param[in] virtualHwBaseAddr - cc base address
93 *
94 * @return - no return value
95 *
96 */
RSA_PKA_SetRegsMapTab(int32_t countOfRegs,int32_t regSizeInPkaWords,unsigned long virtualHwBaseAddr)97 void RSA_PKA_SetRegsMapTab(int32_t countOfRegs,
98 int32_t regSizeInPkaWords,
99 unsigned long virtualHwBaseAddr)
100 {
101 /* LOCAL DECLARATIONS */
102
103 uint32_t currentAddr;
104 int32_t i;
105
106 /* FUNCTION LOGIC */
107 /* start addres of PKA mem. */
108 currentAddr = RSA_PKA_SRAM_REGS_MEM_OFFSET_WORDS;
109
110 /* set addresses of the user requested registers (excluding T0,T1) */
111 for (i = 0; i < countOfRegs-2; i++) {
112 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, MEMORY_MAP0) +
113 i*sizeof(uint32_t), currentAddr);
114 currentAddr += regSizeInPkaWords*RSA_PKA_BIG_WORD_SIZE_IN_32_BIT_WORDS;
115 }
116 /* set addresses of 2 temp registers: T0=30, T1=31 */
117 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, MEMORY_MAP0) + 30*sizeof(uint32_t), currentAddr);
118 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, MEMORY_MAP0) + 31*sizeof(uint32_t),
119 currentAddr + regSizeInPkaWords*RSA_PKA_BIG_WORD_SIZE_IN_32_BIT_WORDS);
120
121 /* set default virtual addresses of N,NP,T0,T1 registers into N_NP_T0_T1_Reg */
122 SB_HAL_WRITE_REGISTER(SB_REG_ADDR(virtualHwBaseAddr, N_NP_T0_T1_ADDR),
123 (uint32_t)RSA_HW_PKI_PKA_N_NP_T0_T1_REG_DEFAULT_VAL);
124
125 return;
126
127 } /* END of the finction PkaSetRegsMapTab */
128
129
130 /*********** PkaInitPka function **********************/
131 /**
132 * @brief This function initializes the PKA engine.
133 *
134 * The function performs the following:
135 * - initializes the PKA_SizesTable, PKA_MappingTable and special register
136 * N_NP_T0_T1 according to user passed register sizes, registers mapping
137 * and default N_NP_T0_T1 value.
138 *
139 * The function calls the PkaSetRegsSizesTab and PkaSetRegsMapTab
140 * functions and sets N_NP_T0_T1 value into N_NP_T0_T1 register.
141 * Notes:
142 * - See remarks to PkaSetRegsSizesTab and PkaSetRegsMapTab functions.
143 * - The function allocates one additional word for each register if it is needed for extra bits.
144 *
145 * @return CCError_t - On success CC_OK is returned, on failure an error code:
146 * PKA_REGISTER_SIZES_ERROR
147 * PKA_ENTRIES_COUNT_ERROR
148 * PKA_NOT_ENOUGH_MEMORY_ERROR
149 *
150 */
RSA_PKA_InitPka(uint32_t opSizeInBits,uint32_t regsCount,unsigned long virtualHwBaseAddr)151 void RSA_PKA_InitPka( uint32_t opSizeInBits, /*in - modulus size in bits*/
152 uint32_t regsCount, /*in*/
153 unsigned long virtualHwBaseAddr) /*in*/
154 {
155
156 /* LOCAL DECLARATIONS */
157
158 uint32_t regSizeInPkaWords;
159
160 /* enabling the PKA clocks */
161 SB_HAL_WRITE_REGISTER( SB_REG_ADDR(virtualHwBaseAddr, PKA_CLK_ENABLE), 0x1UL );
162
163 /* minimal needed regs size */
164 regSizeInPkaWords = GET_FULL_OP_SIZE_PKA_WORDS(opSizeInBits);
165
166
167 /* setting the PKA registers mapping table */
168 /*-----------------------------------------*/
169 RSA_PKA_SetRegsMapTab(regsCount, regSizeInPkaWords, virtualHwBaseAddr);
170
171 /* setting the PKA registers sizes table */
172 /*-----------------------------------------*/
173 RSA_PKA_SetRegsSizesTab(opSizeInBits, regSizeInPkaWords, virtualHwBaseAddr);
174
175 /* ...... End of function ...... */
176 return;
177
178 }
179
180
181 /*********** RSA_HW_PKI_PKA_FinishPKA function **********************/
182 /**
183 * @brief This function ends the PKA engine session and disables PKA clocks.
184 *
185 * @param[in] virtualHwBaseAddr - Virtual HW base address, passed by user.
186 *
187 * @return - no return parameters.
188 *
189 */
RSA_HW_PKI_PKA_FinishPKA(unsigned long virtualHwBaseAddr)190 void RSA_HW_PKI_PKA_FinishPKA( unsigned long virtualHwBaseAddr /*in*/ )
191 {
192
193 /* FUNCTION LOGIC */
194
195 /* close PKA clocks */
196 SB_HAL_WRITE_REGISTER( SB_REG_ADDR(virtualHwBaseAddr, PKA_CLK_ENABLE), 0x0UL );
197
198 }
199
200
201
202 /*******************************************************************************/
203 /************ RSA PKI PKA mathmatic functions and macros ****************/
204 /*******************************************************************************/
205
206
207 /*********** PkaDbgExecOperation (with virtual pointers) ******************/
208 /**
209 * @brief This function executes any allowed PKA mathematic operation according to
210 * user passed Opcode.
211 *
212 * The function receives code of operation, virtual pointers to PKI registers
213 * (sequence number), for arguments and result, and operates PKA machine by writing
214 * full operation code into OPCODE register. Then the function calls macros for
215 * waiting the PKA pipe ready signal.
216 * If opcode is illegal or one of operands is illegal, the function returns an
217 * error code defined in llf_pki_error.h file.
218 *
219 * The user don't call this function directly. For user convenience, in llf_pki.h file are
220 * given some macros for calling this function according to each performed operation.
221 *
222 * NOTES:
223 * - Before executing modular operations, the modulus must be set into N=r0 register of PKA.
224 * - Before modular multiplication and exponentiation must be calculated and set into NP=r1
225 * register the Barrett modulus tag NP = 2**(sizeN+132) / N.
226 * - In operations with immediate operands (IsImmediate bit = 1), the operand value (5-bit)
227 * is treated as sign-extended. That means: low 4 bits are treated as unsigned operand
228 * value in range 0-15 and bit 5 is a sign (with extension to all high bits of register,
229 * in which the full operand shall be set).
230 * - In shift operations the 5-bits shift operand is treated as unsigned value in range 0-31
231 * (count of shifts is equaled to shift operand value + 1).
232 * - The LMul operation gives the low half of multiplication result of length equaled to
233 * operation size. The leading not significant bits of the operands and result (including
234 * the the extra word) must be zeroed.
235 * - The HMul operation gives the high half of multiplication result plus one high word of low
236 * half of full multiplication result. Therefore this result is by one word large, than
237 * operation size. The leading not significant bits of the operands and result,
238 * including extra word must be zeroed.
239 * - The ModInv operation calculates Res = 1/OpB mod N for odd modulus. Operand A is ignored.
240 * In case of even modulus the function returns an error. Therefore in this case
241 * (also for odd modulus) the user may call the PkaExecFullModInv function.
242 *
243 * @param[in] Opcode - The operation code according HW PKA definitions. Valid values: 0 - max Opcode.
244 * @param[in] LenID - ID of the length of operands according to register sizes table
245 * (means the number of entry in the table). Valid values: 0...7.
246 * @param[in] IsAImmed - If IsAImmed = 1, then operand A treated as immediate value, else -
247 * as virtual register pointer. Valid values: 0,1.
248 * @param[in] OpA - Operand A: an immediate value or virtual register pointer, according to IsAImmed
249 * IsAImmed parameter. Valid values: 0 <= OpA <= 31.
250 * @param[in] IsBImmed - If IsBImmed = 1, then operand B treated as immediate value, else -
251 * as virtual register pointer. Valid values: 0,1.
252 * @param[in] OpB - Operand B: an immediate value or virtual register pointer, according to IsAImmed
253 * IsBImmed parameter. Valid values: 0 <= OpA <= 31.
254 * @param[in] ResDiscard - If ResDiscard = 1, then result is discarded.
255 * @param[in] Res - Virtual register pointer for result data.
256 * Valid values: 0 <= Res <= 31. Value Res = RES_DISCARD means result must be discarded.
257 * @param[in] Tag - The user defined value (Tag <= 31), used for indication goals.
258 *
259 *
260 * @return CCError_t - On success CC_OK is returned, on failure an error code:
261 * PKA_ILLEGAL_OPCODE_ERROR
262 * PKA_ILLEGAL_OPERAND_LEN_ERROR
263 * PKA_ILLEGAL_OPERAND_TYPE_ERROR
264 * PKA_ILLEGAL_OPERAND_ERROR
265 * PKA_INVERSION_NOT_EXISTS_ERROR
266 */
267
268
_RSA_PKA_ExecOperation(uint32_t Opcode,uint8_t LenID,uint8_t IsAImmed,int8_t OpA,uint8_t IsBImmed,int8_t OpB,uint8_t ResDiscard,int8_t Res,uint8_t Tag,unsigned long virtualHwBaseAddr)269 CCError_t _RSA_PKA_ExecOperation( uint32_t Opcode, /*in*/
270 uint8_t LenID, /*in*/
271 uint8_t IsAImmed, /*in*/
272 int8_t OpA, /*in*/
273 uint8_t IsBImmed, /*in*/
274 int8_t OpB, /*in*/
275 uint8_t ResDiscard, /*in*/
276 int8_t Res, /*in*/
277 uint8_t Tag, /*in*/
278 unsigned long virtualHwBaseAddr)
279 {
280
281 /* LOCAL DECLARATIONS */
282
283 /* error identification */
284 CCError_t Error = CC_OK;
285
286 /* full Operation Code word */
287 uint32_t FullOpCode;
288
289 /* FUNCTION LOGIC */
290
291 /* if Res == RES_DISCARD , then result is discarded */
292 if (Res == (int8_t)RES_DISCARD) {
293 ResDiscard = 1;
294 Res = 0;
295 }
296
297
298 /*************************************************/
299 /* main PKI operation of this function */
300 /*************************************************/
301
302 FullOpCode = RSA_PKA_FullOpCode(Opcode, LenID, IsAImmed, OpA, IsBImmed, OpB, ResDiscard, Res, Tag);
303 RSA_PKA_WAIT_ON_PKA_PIPE_READY(virtualHwBaseAddr);
304 SB_HAL_WRITE_REGISTER( SB_REG_ADDR(virtualHwBaseAddr, OPCODE), FullOpCode);
305
306
307 /*************************************************/
308 /* finishing operations for different cases */
309 /*************************************************/
310
311 return Error;
312
313 } /* END OF function PkaDbgExecOperation */
314
315
316 /*********** PkaCopyDataIntoPkaReg function **********************/
317 /**
318 * @brief This function copies source data into PKA register .
319 *
320 * Assumings: - PKA is initialized.
321 * - Length of extended (by word) registers is placed into LenID entry of
322 * sizes table.
323 * - If the extra word of register must be cleared also the user must
324 * set LenID according to extended register size
325 *
326 * @param[in] dstReg - Virtual address (number) of destination register.
327 * @param[in] LenId - ID of entry of regsSizesTable, defining full register length,
328 * aligned to PKA word.
329 * @param[in] src_ptr - Pointer to source buffer.
330 * @param[in] sizeWords - Data size in words.
331 *
332 * @return - no return parameters.
333 *
334 */
RSA_HW_PKI_PKA_CopyDataIntoPkaReg(uint32_t dstReg,uint32_t LenID,const uint32_t * src_ptr,uint32_t sizeWords,unsigned long virtualHwBaseAddr)335 void RSA_HW_PKI_PKA_CopyDataIntoPkaReg(uint32_t dstReg, /*out*/
336 uint32_t LenID, /*in*/
337 const uint32_t *src_ptr, /*in*/
338 uint32_t sizeWords, /*in*/
339 unsigned long virtualHwBaseAddr)
340 {
341
342 /* LOCAL DECLARATIONS */
343
344
345 /* current register address and size */
346 uint32_t currAddr;
347 uint32_t regSizeWords;
348
349
350 /* FUNCTION LOGIC */
351
352 /* copy data from src buffer into PKA register with 0-padding *
353 * in the last PKA-word */
354
355 RSA_PKA_WAIT_ON_PKA_DONE(virtualHwBaseAddr);
356 /* register size in 32-bits words */
357 RSA_PKA_ReadRegSize(regSizeWords, LenID, virtualHwBaseAddr);/*temporary in Bits*/
358 regSizeWords = CALC_FULL_32BIT_WORDS(regSizeWords);
359
360 currAddr = RSA_PKA_GetRegAddress(dstReg, virtualHwBaseAddr);
361 RSA_HW_PKI_HW_LOAD_BLOCK_TO_PKA_MEM(virtualHwBaseAddr, currAddr, src_ptr, sizeWords);
362
363 /* zeroe not significant high words of the register */
364 if (regSizeWords > sizeWords){
365 currAddr = currAddr + sizeWords;
366 RSA_HW_PKI_HW_CLEAR_PKA_MEM(virtualHwBaseAddr, currAddr, regSizeWords - sizeWords);
367 }
368
369 #ifdef PKA_DEBUG
370 /*! PKA_DEBUG */
371 //!! RL RSA_PKA_Copy(LenID/*LenID*/, dstReg, dstReg, 0/*Tag*/ , virtualHwBaseAddr);
372 #endif
373 return;
374 } /* END OF function PkaCopyDataIntoPkaReg */
375
376
377
378 /*********** RSA_HW_PKI_PKA_CopyDataFromPkaReg **********************/
379 /**
380 * @brief This function copies data from PKA register into output buffer .
381 *
382 * Assumings: - PKA is initialized.
383 * - Length of extended (by word) registers is placed into LenID entry of
384 * sizes table.
385 * - If the extra word of register must be cleared also the user must
386 * set LenID according to extended register size
387 *
388 * @param[in] srcReg - Virtual address (number) of source PKA register.
389 * @param[in] dst_ptr - Pointer to destination buffer.
390 * @param[in] sizeBytes - Source size in bytes.
391 *
392 * @return - no return parameters.
393 *
394 */
RSA_HW_PKI_PKA_CopyDataFromPkaReg(uint32_t * dst_ptr,uint32_t sizeWords,uint32_t srcReg,unsigned long virtualHwBaseAddr)395 void RSA_HW_PKI_PKA_CopyDataFromPkaReg(uint32_t *dst_ptr, /*out*/
396 uint32_t sizeWords, /*in*/
397 uint32_t srcReg, /*in*/
398 unsigned long virtualHwBaseAddr)
399 {
400
401 /* LOCAL DECLARATIONS */
402
403 /* current register address and size */
404 uint32_t currAddr = 0;
405
406 /* FUNCTION LOGIC */
407
408 RSA_PKA_WAIT_ON_PKA_DONE(virtualHwBaseAddr);
409 currAddr = RSA_PKA_GetRegAddress(srcReg, virtualHwBaseAddr);
410 RSA_HW_PKI_HW_READ_BLOCK_FROM_PKA_MEM(virtualHwBaseAddr, currAddr, dst_ptr, sizeWords );
411
412 return;
413
414 } /* END OF function PkaCopyDataFromPkaReg */
415
416