1 /*
2 * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "cc_pal_mem.h"
8 #include "cc_pal_types.h"
9 #include "cc_pal_mutex.h"
10 #include "cc_hal_plat.h"
11 #include "cc_sram_map.h"
12 #include "dx_crys_kernel.h"
13 #include "cc_common.h"
14 #include "cc_common_math.h"
15 #include "pka_hw_defs.h"
16 #include "pki.h"
17 #include "ec_wrst.h"
18 #include "pka_hw_defs.h"
19 #include "pka.h"
20 #include "pka_error.h"
21 #ifdef DEBUG
22 #include <assert.h>
23 #endif
24
25 extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
26
27 #if defined PKA_DEBUG && defined DEBUG
28 uint32_t tempRes[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS];
29 uint32_t tempRes1[PKA_MAX_REGISTER_SIZE_IN_32BIT_WORDS];
30 #endif
31
32
33 /*********** PkiCalcNp function **********************/
34 /**
35 * The function uses physical data pointers to calculate and output
36 * the Barrett tag Np.
37 *
38 * For RSA it uses truncated sizes:
39 * Np = truncated(2^(3*A+3*X-1) / ceiling(n/(2^(N-2*A-2*X)));
40 * For ECC - full sizes of not truncated input arguments:
41 * Np = truncated(2^(N+A+X-1) / n);
42 *
43 * @author reuvenl (5/1/2014)
44 *
45 * @return CC_OK On success, otherwise indicates failure
46 */
PkiCalcNp(uint32_t * pNp,uint32_t * pN,uint32_t sizeNbits)47 CCError_t PkiCalcNp(uint32_t *pNp, /*!< [out] The pointer to the Barrett tag Np buffer. If pNp = Null,
48 the function not outputs calculated Np. */
49 uint32_t *pN, /*!< [out] The pointer to the modulus n. */
50 uint32_t sizeNbits) /*!< [in] The exact size of the modulus. */
51 {
52 CCError_t err = 0;
53 uint32_t A = CC_PKA_WORD_SIZE_IN_BITS;
54 uint32_t X = PKA_EXTRA_BITS;
55 uint32_t pkaReqRegs = 6;
56 int32_t wN, wNp;
57
58 /* usage of PKA registers */
59 int8_t rN = PKA_REG_N;
60 int8_t rNp = PKA_REG_NP;
61 int8_t rT2 = regTemps[2];
62 int8_t rT4 = regTemps[4];
63
64 /* Calc. sizes of modulus in words and reminder in bits */
65 wN = CALC_FULL_32BIT_WORDS(sizeNbits);
66 wNp = CALC_FULL_32BIT_WORDS(A + X - 1);
67
68 err = PkaInitAndMutexLock(sizeNbits, &pkaReqRegs);
69 if (err != CC_SUCCESS) {
70 CC_PalAbort("Fail to acquire mutex\n");
71 }
72 /* Set modulus in T1 */
73 PkaCopyDataIntoPkaReg(rN/*dstReg*/, LEN_ID_MAX_BITS/*lenId*/, pN/*src_ptr*/, wN);
74 err = PkaCalcNpIntoPkaReg(LEN_ID_N_BITS, sizeNbits, rN /* regN */, rNp /* regNp */, rT2, rT4);
75 if (err != CC_SUCCESS) {
76 goto End;
77 }
78 /* Output Np */
79 PkaCopyDataFromPkaReg(pNp/*dst_ptr*/, wNp, rNp/*srcReg*/);
80 End:
81 PkaFinishAndMutexUnlock(pkaReqRegs);
82
83
84 return err;
85 }
86
87
88 /*********** PkiLongNumDiv function **********************/
89 /**
90 * @brief This function performs division of big numbers, passed by physical pointers,
91 * using the PKA.
92 * .
93 * Computes modRes = A mod B. divRes_ptr = floor(A/B)
94 * Lengths: A[ALen], B[BLen], modRes[BLen], divRes[ALen].
95 * Assumes: c > 0.
96 *
97 * PKA registers using: A=>r2, B=>r3, divRes=>r4, modRes=>r2 (r2 is rewritten by remainder).
98 *
99 * Author: R.Levin
100 *
101 * Last Revision: 1.00.00
102 *
103 * @return CC_OK On success, otherwise indicates failure
104 *
105 * Update History:
106 * Rev 1.00.00, Date 4 Feb. 2008,
107 *
108 */
PkiLongNumDiv(uint32_t * pNumA,uint32_t numASizeInWords,uint32_t * pNumB,uint32_t numBSizeInWords,uint32_t * pModRes,uint32_t * pDivRes)109 CCError_t PkiLongNumDiv(uint32_t *pNumA, /*!< [in] The pointer to numerator A vector. */
110 uint32_t numASizeInWords, /*!< [in] Length of numerator A in words.*/
111 uint32_t *pNumB, /*!< [in] The pointer to divider B (modulus).*/
112 uint32_t numBSizeInWords, /*!< [in] The size of B vector in words.*/
113 uint32_t *pModRes, /*!< [out] The pointer to modulus result (reminder of division). */
114 uint32_t *pDivRes) /*!< [out] The pointer to result of division.*/
115 {
116 CCError_t error = CC_OK;
117 uint32_t opSizeWords;
118 uint32_t status;
119 uint32_t pkaReqRegs = 6;
120 int8_t rT2 = regTemps[2];
121 int8_t rT3 = regTemps[3];
122 int8_t rT4 = regTemps[4];
123
124
125 opSizeWords = CC_MAX(numASizeInWords, numBSizeInWords);
126
127 error = PkaInitAndMutexLock(CC_BITS_IN_32BIT_WORD*opSizeWords, &pkaReqRegs);
128 if (error != CC_OK) {
129 return error;
130 }
131
132 /* copying all needed data into PKA memory before starting PKA operations */
133 /* A=>r2, B=>r3, */
134 /* copy numerator into PKA register: A=>r2 */
135 PkaCopyDataIntoPkaReg( rT2/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pNumA/*src_ptr*/, numASizeInWords);
136
137 /* copy divisor into PKA register: B=>r3 */
138 PkaCopyDataIntoPkaReg( rT3/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pNumB/*src_ptr*/, numBSizeInWords);
139
140 /* check, that divisor is not null, else return error */
141 PKA_ADD_IM( LEN_ID_N_PKA_REG_BITS/*LenID*/, rT4/*Res*/, rT3/*OpA*/, 0/*Imm OpB*/);
142 PKA_GET_STATUS_ALU_OUT_ZERO(status);
143 if (status == 1) {
144 error = PKA_DIVIDER_IS_NULL_ERROR;
145 goto End;
146 }
147
148 /* division in PKA: quotient: r4 = r2 / r3; remainder: r2 = r2 % r3 */
149 PKA_DIV( LEN_ID_N_PKA_REG_BITS/*LenID*/, rT4/*Res*/, rT2/*OpA*/, rT3/*OpB*/);
150
151
152 /* output the results */
153 if (pDivRes != NULL) {
154 PkaCopyDataFromPkaReg(pDivRes, numASizeInWords, rT4/*srcReg*/);
155 }
156
157 if (pModRes != NULL) {
158 PkaCopyDataFromPkaReg(pModRes, numBSizeInWords, rT2/*srcReg*/);
159 }
160
161 End:
162 PkaFinishAndMutexUnlock(pkaReqRegs);
163
164 return error;
165
166 }
167
168
169 /*********** PkiLongNumMul function **********************/
170 /**
171 * @brief This function performs multiplication of big numbers, passed by physical
172 * pointers, using the PKA.
173 *
174 * The RMul operation is : (A * B)
175 *
176 * The function performs the following algorithm:
177 *
178 * @return CC_OK On success, otherwise indicates failure
179 */
PkiLongNumMul(uint32_t * pNumA,uint32_t numASizeInBits,uint32_t * pNumB,uint32_t * pRes)180 CCError_t PkiLongNumMul(uint32_t *pNumA , /*!< [in] The pointer of A words array (LS word is left most). */
181 uint32_t numASizeInBits, /*!< [in] The size of vectors in bits. */
182 uint32_t *pNumB , /*!< [in] The pointer of B words array (LS word is left most). */
183 uint32_t *pRes) /*!< [out] The pointer to the result buffer. */
184 {
185 CCError_t error = CC_OK;
186 uint32_t OpSizeInWords;
187 uint32_t pkaReqRegs = 6;
188 int8_t rT2 = regTemps[2];
189 int8_t rT3 = regTemps[3];
190 int8_t rT4 = regTemps[4];
191
192 #ifdef LLF_PKI_PKA_DEBUG
193 /* check the operands size, used for RSA only */
194 if (2*numASizeInBits > (CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS+CC_PKA_WORD_SIZE_IN_BITS)) {
195 return PKA_ILLEGAL_OPERAND_LEN_ERROR;
196 }
197 #endif
198
199 /* set operation size in words */
200 if (CALC_FULL_32BIT_WORDS(2*numASizeInBits) < CALC_FULL_32BIT_WORDS(PKA_MIN_OPERATION_SIZE_BITS))
201 OpSizeInWords = CALC_FULL_32BIT_WORDS(PKA_MIN_OPERATION_SIZE_BITS);
202
203 else
204 OpSizeInWords = CALC_FULL_32BIT_WORDS(2*numASizeInBits);
205
206
207 error = PkaInitAndMutexLock(CC_BITS_IN_32BIT_WORD*OpSizeInWords, &pkaReqRegs);
208 if (error != CC_OK) {
209 return error;
210 }
211
212 /* copying all needed data into PKA memory before starting PKA operations */
213 /* A=>r2, B=>r3, */
214 /* copy A into PKA register: A=>r2 */
215 PkaCopyDataIntoPkaReg(rT2/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pNumA/*src_ptr*/,
216 CALC_FULL_32BIT_WORDS(numASizeInBits));
217
218 /* copy B into PKA register: B=>r2 */
219 PkaCopyDataIntoPkaReg(rT3/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pNumB/*src_ptr*/,
220 CALC_FULL_32BIT_WORDS(numASizeInBits));
221
222
223 /* multiply in PKA: r4 = r2 * r3; */
224 PKA_MUL_LOW(LEN_ID_N_PKA_REG_BITS/*lenId*/, rT4/*Res*/, rT2/*OpA*/, rT3/*OpB*/);
225
226 /* output the results */
227 PkaCopyDataFromPkaReg(pRes, OpSizeInWords, rT4/*srcReg*/ );
228
229 PkaFinishAndMutexUnlock(pkaReqRegs);
230
231
232 return error;
233 }
234
235
236 /*********** PkiConditionalSecureSwapUint32 function **********************/
237 /**
238 * @brief The function performs conditional swapping of two values in secure
239 * mode
240 *
241 * if(swp == 1) {tmp = *x; *x = *y; *y = tmp;}
242 *
243 * @return None
244 */
PkiConditionalSecureSwapUint32(uint32_t * x,uint32_t * y,uint32_t swp)245 void PkiConditionalSecureSwapUint32(uint32_t *x, /*!< [in/out] the pointer to x-variable. */
246 uint32_t *y, /*!< [in/out] the pointer to y-variable. */
247 uint32_t swp) /*!< [in] swapping condition [0,1]. */
248 {
249 int32_t tmpX = *x;
250 int32_t tmpY = *y;
251 int32_t tmp = tmpX ^ tmpY;
252
253 swp = -swp;
254 tmp &= swp;
255 *x = tmpX ^ tmp;
256 *y = tmpY ^ tmp;
257 }
258
259
260 /*********** PkiClearAllPka function **********************/
261 /**
262 * @brief This function clears the PKA memory.
263 *
264 * @return None
265 */
PkiClearAllPka(void)266 void PkiClearAllPka(void)
267 {
268 uint32_t pkaRegCount = PKA_MAX_COUNT_OF_PHYS_MEM_REGS;
269 uint32_t regSizeInBits = ((CC_PKA_SRAM_SIZE_IN_KBYTES*CC_1K_SIZE_IN_BYTES*CC_BITS_IN_BYTE)/PKA_MAX_COUNT_OF_PHYS_MEM_REGS)-CC_PKA_WORD_SIZE_IN_BITS;
270
271 if (PkaInitAndMutexLock(regSizeInBits, &pkaRegCount) != CC_SUCCESS) {
272 return;
273 }
274
275 PkaFinishAndMutexUnlock(pkaRegCount);
276 return;
277
278 }
279
280 /*!< get next two bits of scalar*/
PkiGetNextTwoMsBits(uint32_t * pScalar,uint32_t * pWord,int32_t i)281 uint32_t PkiGetNextTwoMsBits(uint32_t *pScalar, uint32_t *pWord, int32_t i)
282 {
283 uint32_t twoBits = 0;
284 // twoBits = (*pWord >> (i & (CC_BITS_IN_32BIT_WORD - 1))) & 3;
285 twoBits = (*pWord >> (CC_BITS_IN_32BIT_WORD - 2));
286 /* get next bit of scalar */
287 if ((i % CC_BITS_IN_32BIT_WORD) != 0) {
288 *pWord <<= 2;
289 } else {
290 *pWord = pScalar[(i / CC_BITS_IN_32BIT_WORD)-1];
291 }
292 // i--;
293
294 return twoBits;
295 }
296
297
298 /*!< the function checks is array equal to 0: *
299 * if arr == 0, then return 0, else 1. */
PkiIsUint8ArrayEqualTo0(const uint8_t * arr,size_t size)300 bool PkiIsUint8ArrayEqualTo0(const uint8_t *arr, size_t size)
301 {
302 uint32_t i;
303 uint8_t s = 0;
304 for (i = 0; i < size; i++)
305 s |= arr[i];
306 /* if(arr == 0) return 1, else 0. */
307 return !(bool)((0UL - s) >> 31);
308
309 }
310
311 /*!< the function compares equality of two buffers of same size:
312 if they are equal - return 0, else 1. */
PkiAreBuffersEqual(const void * buff1,const void * buff2,size_t sizeInBytes)313 bool PkiAreBuffersEqual(const void *buff1, const void *buff2, size_t sizeInBytes)
314 {
315 uint32_t i;
316 uint8_t s = 0;
317 for (i = 0; i < sizeInBytes; i++)
318 s |= (((uint8_t*)buff1)[i] ^ ((uint8_t*)buff2)[i]);
319 /* if equalled return 0, else 1. */
320 return !(bool)((0UL - s) >> 31);
321
322 }
323
324 /************************************************************************/
325 /**
326 * @brief The function copies uint8 big endianness data into PKA register.
327 *
328 * Notes: Assumed all parameters are checked before calling this function.
329 * PKA registers used: dstReg.
330 * The size of pTemp buffer is at least PKA register size (appropriate to
331 * register size lenID) and dataSizeBytes <= temp buffer size (in bytes).
332 *
333 * @return no return value
334 */
PkaCopyBe8DataIntoPkaReg(uint32_t dstReg,uint32_t lenId,const uint8_t * pSrc,uint32_t dataSizeBytes,uint32_t * pTemp)335 void PkaCopyBe8DataIntoPkaReg(uint32_t dstReg, /* [out] virtual pointer to destination PKA register. */
336 uint32_t lenId, /* [in] PKA register length ID.*/
337 const uint8_t *pSrc, /* [in] pointer to source buffer. */
338 uint32_t dataSizeBytes, /* [in] size of the data in bytes */
339 uint32_t *pTemp) /* [in] pointer to the temp buffer of
340 size >= PKA SRAM register size. */
341 {
342 uint32_t regSizeBits, regSizeWords;
343 // uint32_t currAddr, word, dataSizeWords;
344 // int32_t i, j = 0;
345
346 PKA_GET_REG_SIZE(regSizeBits, lenId);
347 regSizeWords = CALC_FULL_32BIT_WORDS(regSizeBits); /*size in words*/
348
349 // CC_CommonConvertMsbLsbBytesToLswMswWords(pTemp, regSizeWords*CC_32BIT_WORD_SIZE, pSrc, dataSizeBytes);
350 CC_PalMemSetZero((uint8_t*)pTemp + dataSizeBytes, regSizeWords*CC_32BIT_WORD_SIZE - dataSizeBytes);
351 CC_CommonReverseMemcpy((uint8_t*)pTemp, (uint8_t*)pSrc, dataSizeBytes);
352 // dataSizeWords = CALC_32BIT_WORDS_FROM_BYTES(dataSizeBytes);
353 PkaCopyDataIntoPkaReg(dstReg, lenId, pTemp, regSizeWords);
354
355 // dataSizeWords = CALC_32BIT_WORDS_FROM_BYTES(dataSizeBytes);
356 // PKA_GET_REG_ADDRESS(dstReg, currAddr);
357 //
358 // if(i > 3) {
359 // for(i = dataSizeBytes-1; i > 0; i -= 4, j++) {
360 // word = (pSrc[i] << 24) | (pSrc[i-1] << 16) |
361 // (pSrc[i-2] << 8) | pSrc[i-3];
362 // PKA_HW_LOAD_VALUE_TO_PKA_MEM(currAddr, word);
363 // currAddr += CC_32BIT_WORD_SIZE;
364 // }
365 return;
366 }
367
368
369 /************************************************************************/
370 /**
371 * @brief The function copies data from PKA register into uint8 buffer in big endianness order.
372 *
373 * Notes: Assumed all parameters are checked before calling this function.
374 * PKA registers used: srcReg.
375 * The size (in 32-bit words) of pTemp buffer is at least the data size,
376 * in words (rounded up).
377 *
378 * @return no return value
379 */
PkaCopyDataFromPkaRegToBe8Buff(uint8_t * pDst,uint32_t srcReg,uint32_t sizeBytes,uint32_t * pTemp)380 void PkaCopyDataFromPkaRegToBe8Buff(
381 uint8_t *pDst, /* [out] pointer to the destination buffer of size >= sizeBytes. */
382 uint32_t srcReg, /* [in] virtual pointer to source PKA register. */
383 uint32_t sizeBytes, /* [in] size of the data in PKA register in bytes */
384 uint32_t *pTemp) /* [in] pointer to the temp buffer of size (in bytes) >= sizeBytes. */
385 {
386 PkaCopyDataFromPkaReg(pTemp, CALC_32BIT_WORDS_FROM_BYTES(sizeBytes), srcReg);
387 CC_CommonReverseMemcpy(pDst, (uint8_t*)pTemp, sizeBytes);
388
389 return;
390 }
391
392
393
394 /*********** PkiExecExpBe function **********************/
395 /**
396 * @brief Executes the modular exponentiation using PKA for BE input parameters.
397 *
398 * The function input/output arrays are in big endianness order of bytes.
399 *
400 * Notes: Assumed all parameters are checked before calling this function.
401 * All sizes aligned to 32-bit words, leading zeros are present if exist.
402 * PKA registers used: r0,r1,r2,r3,r4, r30,r31.
403 * The size of pTemp buffer should be at least modulus size plus 2*PKA_WORD_SIZE,
404 * where all sizes are rounded up to uint32 size.
405 *
406 * @return no return value
407 */
PkiExecModExpBe(uint8_t * pOut,uint8_t * pIn,uint32_t inSizeBytes,uint8_t * pMod,uint32_t modSizeBits,uint8_t * pExp,uint32_t expSizeBytes,uint32_t * pTemp)408 CCError_t PkiExecModExpBe(
409 uint8_t *pOut, /* [out] pointer to the exponentiation result with size >= modulus size (in bytes),
410 equaled to modulus size in bytes (including leading zeros. */
411 uint8_t *pIn, /* [in] pointer to the input data. */
412 uint32_t inSizeBytes, /* [in] input data size in bytes */
413 uint8_t *pMod, /* [in] pointer to the modulus. */
414 uint32_t modSizeBits, /* [in] modulus size in bits */
415 uint8_t *pExp, /* [in] pointer to the exponent buffer. */
416 uint32_t expSizeBytes,/* [in] exponent size in bytes; should be <= modulus size (in bytes). */
417 uint32_t *pTemp) /* [in] pointer to the temp buffer of size >= modulus size. */
418 {
419 CCError_t err = CC_OK;
420 uint32_t modSizeBytes;
421 uint32_t pkaRegsCount = 7;
422 /* define virtual registers pointers */
423 #define IN_REG 2
424 #define EXP_REG 3
425 #define OUT_REG 4
426
427
428 err = PkaInitAndMutexLock(modSizeBits, &pkaRegsCount);
429 if (err != CC_OK) {
430 return err;
431 }
432
433 modSizeBytes = CALC_FULL_BYTES(modSizeBits);
434
435 /* copy modulus into PKA */
436 PkaCopyBe8DataIntoPkaReg(PKA_REG_N/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pMod/*srcPtr*/,
437 modSizeBytes, pTemp);
438
439 /* Calculate NP */
440 err = PkaCalcNpIntoPkaReg(LEN_ID_N_BITS,
441 modSizeBits, /* [in] The exact size of the modulus. */
442 PKA_REG_N, /* [in] PKA reg, holding the modulus n. */
443 PKA_REG_NP, /* [out PKA reg. - Np result. */
444 IN_REG, OUT_REG); /* PKA regs, used as temporaries. */
445
446 if (err != CC_OK) {
447 goto End;
448 }
449
450
451 /* copy the Data and Exponent into PKA registers */
452 PkaCopyBe8DataIntoPkaReg(IN_REG/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pIn, inSizeBytes, pTemp);
453 PkaCopyBe8DataIntoPkaReg(EXP_REG/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pExp, expSizeBytes, pTemp);
454
455 /* calculate the exponent result: OUT_REG */
456 PKA_MOD_EXP(LEN_ID_N_BITS/*LenID*/, OUT_REG, IN_REG/*OpA*/, EXP_REG/*OpB*/);
457
458 /* output result as big endiannness bytes array */
459 PkaCopyDataFromPkaRegToBe8Buff(pOut, OUT_REG, modSizeBytes, pTemp);
460
461 End:
462 /* Finish PKA and copy result */
463 PkaFinishAndMutexUnlock(pkaRegsCount);
464
465 /* undef virtual registers pointers */
466 #undef IN_REG
467 #undef EXP_REG
468 #undef OUT_REG
469
470 return err;
471
472 }
473
474 /*********** PkiExecExpLeW function **********************/
475 /**
476 * @brief Executes modular exponentiation using PKA for LE input parameters.
477 *
478 * The function input/output arrays are given as little endianness words arrays.
479 *
480 * Notes: Assumed all parameters are checked before calling this function.
481 * All sizes aligned to 32-bit words, leading zeros are present if exist.
482 * PKA registers used: r0,r1,r2,r3,r4, r30,r31.
483 *
484 * @return no return value
485 */
PkiExecModExpLeW(uint32_t * pOut,uint32_t * pIn,uint32_t inSizeWords,uint32_t * pMod,uint32_t modSizeBits,uint32_t * pExp,uint32_t expSizeWords)486 CCError_t PkiExecModExpLeW(
487 uint32_t *pOut, /* [out] pointer to the exponentiation result with size, equalled
488 to modulus size in words (including leading zeros). */
489 uint32_t *pIn, /* [in] pointer to the input data. */
490 uint32_t inSizeWords, /* [in] input data size in words */
491 uint32_t *pMod, /* [in] pointer to the modulus. */
492 uint32_t modSizeBits, /* [in] modulus size in bits */
493 uint32_t *pExp, /* [in] pointer to the exponent buffer. */
494 uint32_t expSizeWords) /* [in] exponent size: should be <= modulus size (in words). */
495 {
496 CCError_t err = CC_OK;
497 uint32_t modSizeWords;
498 uint32_t pkaRegsCount = 7;
499 /* define virtual registers pointers */
500 #define IN_REG 2
501 #define EXP_REG 3
502 #define OUT_REG 4
503
504
505 err = PkaInitAndMutexLock(modSizeBits, &pkaRegsCount);
506 if (err != CC_OK) {
507 return err;
508 }
509
510 modSizeWords = CALC_FULL_32BIT_WORDS(modSizeBits);
511
512 /* copy modulus into PKA */
513 PkaCopyDataIntoPkaReg(PKA_REG_N/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/,
514 pMod/*srcPtr*/, modSizeWords);
515
516 /* Calculate NP */
517 err = PkaCalcNpIntoPkaReg(LEN_ID_N_BITS,
518 modSizeBits, /* [in] The exact size of the modulus. */
519 PKA_REG_N, /* [in] PKA reg, holding the modulus n. */
520 PKA_REG_NP, /* [out PKA reg. - Np result. */
521 IN_REG, OUT_REG); /* PKA regs, used as temporaries. */
522 if(err) {
523 goto End;
524 }
525
526 /* copy the Data and Exponent into PKA registers */
527 PkaCopyDataIntoPkaReg(IN_REG/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pIn, inSizeWords);
528 PkaCopyDataIntoPkaReg(EXP_REG/*dstReg*/, LEN_ID_MAX_BITS/*LenID*/, pExp, expSizeWords);
529
530 /* calculate the exponent result: OUT_REG */
531 PKA_MOD_EXP(LEN_ID_N_BITS/*LenID*/, OUT_REG, IN_REG/*OpA*/, EXP_REG/*OpB*/);
532
533 /* output result as big endiannness bytes array */
534 PkaCopyDataFromPkaReg(pOut, modSizeWords, OUT_REG);
535
536 End:
537 /* Finish PKA and copy result */
538 PkaFinishAndMutexUnlock(pkaRegsCount);
539
540 /* undef virtual registers pointers */
541 #undef IN_REG
542 #undef EXP_REG
543 #undef OUT_REG
544
545 return err;
546
547 }
548
549
550
551