1 /*
2 * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifdef CC_IOT
8 #include "mbedtls/build_info.h"
9 #endif
10
11 #if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
12
13 #include "cc_pal_types.h"
14 #include "cc_rsa_types.h"
15 #include "cc_rsa_error.h"
16 #include "cc_rsa_local.h"
17 #include "cc_common_math.h"
18 #include "cc_rnd_common.h"
19 #include "cc_rnd_error.h"
20 #include "pka.h"
21 #include "pka_error.h"
22 #include "pki.h"
23 #include "pka_hw_defs.h"
24 #include "cc_pal_mem.h"
25 #include "rsa_public.h"
26 #include "rsa_private.h"
27 #include "rsa.h"
28 #ifdef FIPS_CERTIFICATION
29 #include "fips_tests_rsa_def.h"
30 #include "cc_common.h"
31 #endif
32
33 /* canceling the lint warning:
34 Info 716: while(1) ... */
35 /*lint --e{716} */
36 /* canceling the lint warning: Constant value Boolean
37 Warning 506 regarding while(1) ... */
38 /*lint --e{506} */
39
40 /* canceling the lint warning:
41 Info 506: Constant value Boolean ... */
42 /*lint --e{506} */
43
44 /* canceling the lint warning:
45 Info 774: Boolean within 'if' always evaluates to False */
46 /*lint --e{774} */
47
48 /************************ Defines ******************************/
49
50 #define RSA_QUICK_PRIME_TEST_DIVISIONS_COUNT 128
51
52 #define CALC_PRIME_PRODUCT_NUM ( CC_MIN(CALC_FULL_32BIT_WORDS(CC_RSA_MAX_KEY_GENERATION_SIZE_BITS),CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS) )
53 #define PRIME_PRODUCT_BUFF_SIZE ( CC_MAX(CALC_FULL_32BIT_WORDS(CC_RSA_MAX_KEY_GENERATION_SIZE_BITS),CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS) )
54 #define PRIME_NUM 256
55
56 #define CALC_PRIME_PRODUCT (CALC_PRIME_PRODUCT_NUM/2 - 3)
57
58 #if (CALC_PRIME_PRODUCT > (CC_PKA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS-6))
59 #error ("CALC_PRIME_PRODUCT > (CC_PKA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS-6)")
60 #endif
61
62
63 /************************ Global Data ******************************/
64 #ifdef FIPS_CERTIFICATION
65 rsaKgInternalPrime_t prim1Int;
66 rsaKgInternalPrime_t prim2Int;
67 extern rsaKgInternalDataStruct_t rsaKgOutParams;
68 rsaKgInternalPrime_t *primeInt = NULL;
69 #endif
70
71
72 extern const int8_t regTemps[PKA_MAX_COUNT_OF_PHYS_MEM_REGS];
73
74 const uint32_t g_PrimeProduct[PRIME_PRODUCT_BUFF_SIZE] = {
75 3234846615UL,95041567UL,907383479,4132280413UL,121330189,257557397UL,490995677,842952707,
76 1314423991UL,2125525169UL,3073309843UL,16965341,20193023,23300239,29884301,35360399,
77 42749359UL,49143869,56466073,65111573,76027969,84208541,94593973,103569859,119319383,133390067UL,
78 154769821UL,178433279,193397129,213479407,229580147,250367549,271661713,293158127,319512181,
79 357349471UL,393806449,422400701,452366557,507436351,547978913,575204137,627947039,666785731,
80 710381447UL,777767161UL,834985999UL,894826021UL,951747481UL,1019050649UL,1072651369UL,1125878063UL,1185362993UL,
81 1267745273UL,1322520163UL,1391119619UL,1498299287UL,1608372013UL,1700725291UL,1805418283UL,1871456063UL,
82 2008071007UL,2115193573UL,2178429527UL,2246284699UL,2385788087UL
83 };
84
85 const uint16_t g_SmallPrime[PRIME_NUM] =
86 {
87 3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,
88 113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,
89 229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,
90 359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,
91 487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,
92 619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,
93 761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,
94 911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,
95 1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,
96 1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,
97 1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,
98 1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,
99 1579,1583,1597,1601,1607,1609,1613,1619,1621
100 };
101
102 const uint16_t g_LastProductPrime[PRIME_PRODUCT_BUFF_SIZE] =
103 {
104 9,14,19,24,28,32,36,40,44,48,52,55,58,61,64,67,70,73,76,79,82,85,88,91,94,97,100,103,106,109,112,
105 115,118,121,124,127,130,133,136,139,142,145,148,151,154,157,160,163,166,169,172,175,178,181,
106 184,187,190,193,196,199,202,205,208,211,214,217
107
108 };
109
110
111 extern CCError_t RndGenerateWordsArrayInRange(CCRndContext_t *pRndContext,
112 uint32_t rndSizeInBits,
113 uint32_t *maxVect_ptr,
114 uint32_t *rndVect_ptr,
115 uint32_t *tmp_ptr);
116
117 /*********** PkaRsaKgX931Jacobi function **********************/
118 /**
119 * @brief Calculates Jacobi index.
120 * If there is such a vector b, that satisfies the condition b^2 = a mod p, the result is 1.
121 * If there is no such vector, the result is -1.
122 *
123 * @return CC_OK On success, otherwise indicates failure
124 */
PkaRsaKgX931Jacobi(uint32_t lenId,int8_t rA,int8_t rP,int32_t * pJacobiRes,int8_t rA1,int8_t rP1,int8_t rT)125 static CCError_t PkaRsaKgX931Jacobi (uint32_t lenId, /*!< [in] The RegsSizesTable entry, containing the exact size of vector p in bits. */
126 int8_t rA, /*!< [in] Virtual pointer to the base vector. */
127 int8_t rP, /*!< [in] Virtual pointer to the prime to be tested (the modulos). */
128 int32_t *pJacobiRes, /*!< [out] Pointer to the result var (1,0,-1) as described in the description. */
129 int8_t rA1, /*!< [in] virtual pointers to temp PKA registers. */
130 int8_t rP1, /*!< [in] virtual pointers to temp PKA registers. */
131 int8_t rT) /*!< [in] virtual pointers to temp PKA registers. */
132 {
133 int32_t k, s;
134 uint32_t residue;
135 uint32_t bitVal;
136 uint32_t status;
137 /* low words of A1 and P1 */
138 uint32_t A1_0, P1_0;
139 /* temp swap value */
140 int8_t rSw;
141
142 /* copy the input vectors with extension */
143 PKA_COPY(LEN_ID_MAX_BITS, rA1/*dest*/, rA/*src*/);
144 PKA_COPY(LEN_ID_MAX_BITS, rP1/*dest*/, rP/*src*/);
145
146 /* initialize the result as 1 ( default ) */
147 *pJacobiRes = 1;
148
149 /* step 3. if a1 == 1, return - we have done */
150 PKA_COMPARE_IM_STATUS(lenId+1, rA1/*OpA*/, 1/*OpB*/, status);
151 if (status == 1) {
152 return CC_OK;
153 }
154
155
156 // do loop for finding the jacobi
157 do {
158 // Step 1. If a == 0, return the result 0
159 PKA_COMPARE_IM_STATUS(lenId+1, rA1/*OpA*/, 0/*OpB*/, status);
160 if (status == 1) {
161 *pJacobiRes = 0;
162 return CC_OK;
163 }
164
165
166 // Step 2. Find out larger power of two for A1
167 k = 0;
168
169 /* check parity of A1 */
170 PKA_READ_BIT0(lenId+1, rA1/*OpA*/, bitVal);
171 while (bitVal == 0) {
172 /* divide by 2 */
173 PKA_SHR_FILL0(lenId+1, rA1/*Res*/, rA1/*OpA*/, 1-1/*S*/);
174 PKA_READ_BIT0(lenId+1, rA1/*OpA*/, bitVal);
175 k++;
176 }
177
178 // get low bytes of A1 and P1
179 PKA_READ_WORD_FROM_REG(A1_0, 0, rA1);
180 PKA_READ_WORD_FROM_REG(P1_0, 0, rP1);
181
182 /* initialize s as 0 */
183 s = 0;
184
185 // step 3. if k is even set s=1
186 if ((k & 1) == 0) {
187 s = 1;
188 } else {
189 /* else set s=1 if p = 1 or 7 (mod 8) or s=-1 if p = 3 or 5 (mod 8) */
190 residue = P1_0 & 7;
191
192 if (residue == 1 || residue == 7) {
193 s = 1;
194 } else if (residue == 3 || residue == 5) {
195 s = -1;
196 }
197 }
198
199 // Step 4. If p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s
200 if (((P1_0 & 3) == 3) && ((A1_0 & 3) == 3)) {
201 s = -s;
202 }
203
204 /* Step 5 : Update the result */
205 *pJacobiRes *= s;
206
207
208 // Step 6. If a1 == 1, return - done
209 PKA_COMPARE_IM_STATUS(lenId+1, rA1/*OpA*/, 1/*OpB*/, status);
210 if (status == 1) {
211 return CC_OK;
212 }
213
214 /* p1 = p1 mod a1 - the result is at rP1 register */
215 PKA_DIV(lenId+1 , rT/*ResNotUsed*/, rP1/*OpA*/, rA1/*OpB*/);
216
217 // Step 7. Exchange P1 & A1
218 rSw = rP1;
219 rP1 = rA1;
220 rA1 = rSw;
221
222 }while (1); /* end of do loop */
223 }
224
225
226
227 /*********** PkaRsaKgX931MillerRabinTest function **********************/
228 /**
229 * @brief Executes the rabin miller test according to the the ANS X9.31 standard.
230 *
231 * Algorithm:
232 * 1. Let: prime candidate P = 1 + 2^a * m, where: m is odd and a > 0.
233 * 2. For( i = 0; i < countTests; i++ ) do
234 * 2.1. Generate random number b in range 1 < b < P.
235 * 2.2. Calculate z = b^m mod P.
236 * 2.3. If z = 1, or z = P-1, then goto st.6.
237 * 2.4. For(j = 1; j < a; j++ ) do
238 * 2.4.1. set z = z^2 mod P
239 * 2.4.2. If z = P-1, then goto st.6.
240 * 2.4.3. If z = 1, then output "composite" and stop.
241 * End for //2.4.
242 * 2.5. Output "composite". Stop.
243 * End for //2.
244 * 3. Output P is "probable prime". Stop.
245 *
246 * Assumings: - PKA is initialised on default mode for prime P as modulus (see near);
247 * - the registers sizes table and mapping table are set on default mode,
248 * according to exact P size, that means:
249 * -- registers sizes table entries are set by default as follows:
250 * lenId - P_sizeBits, lenId+1 - (32*P_sizeWords + 32 bit);
251 * - the prime candidate P is inserted in the modulus register PKA_REG_N;
252 * - the Barrett tag NP for P is inserted into register 1;
253 * - the PKA clocks are initialized.
254 *
255 * NOTE: - It uses 7 PKA data registers: PKA_REG_N,PKA_REG_NP,30,31, and 3 temp registers.
256 *
257 * Assumptions : the max size supported is 2112 bits.
258 *
259 * @return CC_OK On success, otherwise indicates failure
260 */
PkaRsaKgX931MillerRabinTest(CCRndContext_t * pRndContext,uint32_t lenId,uint32_t modulusSizeInBits,int8_t * pSuccessCode,uint8_t testsCount,int8_t rT0,int8_t rT1,int8_t rT2,uint32_t * pTempBuff)261 static CCError_t PkaRsaKgX931MillerRabinTest(CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
262 uint32_t lenId, /*!< [in] The ID of entry in RegsSizesTable, containing modulusSizeInBits. */
263 uint32_t modulusSizeInBits, /*!< [in] The prime candidate size. */
264 int8_t *pSuccessCode, /*!< [out] the success code : 0 - the test failed , 1 the test passed. */
265 uint8_t testsCount, /*!< [in] Count of exponentiations in test. If CountTests = 0, then
266 CountTests will be set automatically according to prime size. */
267 int8_t rT0, /*!< [in] Virtual pointer to the base vector. */
268 int8_t rT1, /*!< [in] Virtual pointer to the base vector. */
269 int8_t rT2, /*!< [in] Virtual pointer to the base vector. */
270 uint32_t *pTempBuff) /*!< [in] pointer to temp buffer of size 3*modulusSizeInWords. */
271 {
272 CCError_t error = CC_OK;
273 uint32_t i, j;
274 uint32_t aValue, pSizeInWords;
275 uint32_t status;
276 uint32_t bitVal;
277 uint32_t *pTempP, *pTempB;
278
279 /* prime size in words */
280 pSizeInWords = CALC_FULL_32BIT_WORDS(modulusSizeInBits);
281
282 // first pSizeInWords of pTempBuff is used as temprary buffer by RndGenerateWordsArrayInRange
283 pTempP = &pTempBuff[pSizeInWords];
284 pTempB = &pTempBuff[2*pSizeInWords];
285
286 /* clearing the temp registers */
287 PKA_2CLEAR(LEN_ID_MAX_BITS, rT0/*regNum*/);
288 PKA_2CLEAR(LEN_ID_MAX_BITS, rT1/*regNum*/);
289 PKA_2CLEAR(LEN_ID_MAX_BITS, rT2/*regNum*/);
290
291 // St. 1.2. Calculate a and m such, that P = 1 + 2^a * m ; m=>rT0, a=>aValue
292 /* copy P into register rT0 */
293 PKA_COPY(LEN_ID_MAX_BITS, rT0/*dst*/, PKA_REG_N/*src=P*/);
294
295 /* rT0 = P - 1 */
296 PKA_SUB_IM( lenId+1, rT0/*Res*/, rT0/*P*/, 1/*imm*/);
297
298 /* set P-1 in tempP buff */
299 PkaCopyDataFromPkaReg(pTempP, pSizeInWords, rT0/*srcReg*/);
300
301 /* a = 1 */
302 aValue = 1;
303
304 while (1) {
305 /* divide: rT0 = rT0 / 2 */
306 PKA_SHR_FILL0(lenId+1, rT0/*Res*/, rT0/*P*/, 1-1/*OpB*/);
307
308 /* test parity of rT0 */
309 PKA_READ_BIT0(lenId+1, rT0/*P*/, bitVal);
310 if (bitVal == 0) {
311 aValue++;
312 } else {
313 break;
314 }
315 }
316
317 // St. 2. Rabin-Miller test main loop
318 *pSuccessCode = CC_TRUE;
319
320 for (i = 0 ; i < testsCount ; ++i) {
321 // St. 2.1. Prepare a random number b, used for the Rabin-Miller test */
322 // as the Base of exponentiation. The number must be not larger, than
323
324 /* generate a random number b=>rT1 for testing the primality of P by *
325 * exponentiation */
326 CC_PalMemSetZero(pTempB, sizeof(uint32_t)*pSizeInWords);
327 error = RndGenerateWordsArrayInRange(
328 pRndContext,
329 modulusSizeInBits,
330 pTempP/*(P-1) - maxVect*/,
331 pTempB/*Rnd*/,
332 pTempBuff/*temp buff*/);
333 if (error != CC_OK) {
334 return error;
335 }
336
337 PkaCopyDataIntoPkaReg( rT1/*dstReg*/, LEN_ID_MAX_BITS, pTempB/*src_ptr*/, pSizeInWords);
338
339 // St. 2.2. Calculate: z = rT1 = z^m mod P; Set j = 0.
340 PKA_MOD_EXP( lenId, rT1/*Res=z*/, rT1/*opA=b*/, rT0/*OpB=m*/);
341
342 // St. 2.3. Check; if z = 1 or z = P-1, then generate next B
343 /* z == 1 ? */
344 PKA_COMPARE_IM_STATUS(lenId+1, rT1/*z*/, 1/*OpB*/, status);
345 if (status == 1) {
346 goto passed_this_iteration;
347 }
348
349 /* rT2 = P - 1 */
350 PKA_SUB_IM( lenId+1, rT2/*Res*/, PKA_REG_N/*P*/, 1/*OpB*/);
351
352 /* z == P-1 ? */
353 PKA_COMPARE_STATUS(lenId+1, rT2/*P*/, rT1/*OpB*/, status);
354 if (status == 1) {
355 goto passed_this_iteration;
356 }
357
358 // St. 2.4. Loop: do while not meet conditions
359 // (j == 0 && z == 1) or (z== P-1 )
360 for (j = 1; j < aValue; j++) {
361 /* St. 2.4.1. z= z^2 mod m */
362 PKA_MOD_MUL( lenId, rT1/*Res*/, rT1/*P*/, rT1/*OpB*/);
363
364 /* St. 2.4.2. if z == P-1, then break and next i */
365 PKA_COMPARE_STATUS(lenId+1, rT2/*P*/, rT1/*OpB*/, status);
366 if (status == 1) {
367 goto passed_this_iteration;
368 }
369
370 /* St. 2.4.3. if z == 1, then output composite and stop */
371 PKA_COMPARE_IM_STATUS(lenId+1, rT1/*P*/, 1/*OpB*/, status);
372 if (status == 1) {
373 *pSuccessCode = CC_FALSE;
374 goto End;
375 }
376
377 }/* end for */
378
379 *pSuccessCode = CC_FALSE;
380 goto End;
381
382 passed_this_iteration: ;
383
384 } /* end main for */
385 End:
386
387 /* delete secure sensitive data and exit */
388 aValue = 0;
389 /* clear temp and tempP */
390 CC_PalMemSetZero(pTempBuff, 3*sizeof(uint32_t)*pSizeInWords);
391
392 return error;
393 }
394
395
396 /*********** PkaRsaKgX931LucasPrimeTest function **********************/
397 /**
398 * @brief Executes the Lucas test according to the the X931 standard.
399 *
400 * Assumptions : the max size supported is 2112 bits.
401 *
402 * @return CC_OK On success, otherwise indicates failure
403 */
PkaRsaKgX931LucasPrimeTest(uint32_t lenId,int8_t * pSuccessCode,const int8_t * pRegTemps,uint32_t tempsCount)404 static CCError_t PkaRsaKgX931LucasPrimeTest(uint32_t lenId, /*!< [in] The ID of entry in RegsSizesTable, containing exact size of P in bits. */
405 int8_t *pSuccessCode, /*!< [out] Success code : 0 - the test failed , 1 the test passed. */
406 const int8_t *pRegTemps, /*!< [in] Pointer to temp registers list - 7 registers. */
407 uint32_t tempsCount) /*!< [in] Count of temp registers in the list. */
408 {
409 CCError_t error;
410 uint32_t kSizeInBits;
411 uint32_t d_abs;
412 int8_t d_is_positive;
413 int32_t JacobiRes;
414 int32_t i;
415 uint32_t status;
416 /* virtual pointers to registers */
417 int8_t rP, rD, rK, rU, rV, rUnew, rVnew, rT;
418
419 /* check temp registers count */
420 #ifdef LLF_PKI_PKA_DEBUG
421 if (tempsCount < 7)
422 return PKA_NOT_ENOUGH_TEMP_REGS_ERROR;
423 #else
424 tempsCount= tempsCount;
425 #endif
426
427 rP = PKA_REG_N; /* already is initialized by P */
428 rD = pRegTemps[0];
429 rK = pRegTemps[1];
430 rU = pRegTemps[2];
431 rV = pRegTemps[3];
432 rUnew = pRegTemps[4];
433 rVnew = pRegTemps[5];
434 rT = pRegTemps[6];
435
436
437 // setting the d vector
438 /* clear the temp buffer */
439 PKA_2CLEAR(LEN_ID_MAX_BITS, rD/*regNum*/);
440
441 for (d_abs = 5 , d_is_positive = 1 ; ; d_abs+=2 , d_is_positive = !d_is_positive) {
442 /* set D = d_abs */
443 PKA_WRITE_WORD_TO_REG(d_abs, 0, rD);
444
445 /* if D is negative set D = P - D */
446 if (d_is_positive == 0) {
447 PKA_SUB( lenId+1, rD/*Res*/, rP/*P*/, rD/*OpB*/);
448 }
449
450 error = PkaRsaKgX931Jacobi( lenId, rD, rP, &JacobiRes,
451 rU/*temp*/, rV/*temp*/, rT/*temp*/);
452
453 if (error != CC_OK) {
454 return error;
455 }
456
457 if (JacobiRes == -1) {
458 break;
459 }
460
461 }/* end of loop for finding d */
462
463
464 // init vectors for the test loop
465 /* K = P + 1 */
466 PKA_ADD_IM( lenId+1, rK/*Res*/, rP/*P*/, 1/*OpB*/);
467
468 /* set the size of K in bits */
469 kSizeInBits = PkaGetRegEffectiveSizeInBits(rK/*reg*/);
470
471 /* init U and V to 1 */
472 PKA_2CLEAR(LEN_ID_MAX_BITS, rU/*regNum*/);
473 PKA_SET_BIT0(lenId+1, rU/*Res*/, rU/*regNum*/);
474 PKA_COPY(LEN_ID_MAX_BITS, rV/*dest*/, rU/*src*/);
475
476
477 // the main test loop
478 for (i = (int32_t)(kSizeInBits - 2) ; i >= 0 ; --i) {
479 /* a bit value */
480 uint32_t bit;
481
482 /* Unew = U*V mod P */
483 PKA_MOD_MUL( lenId, rUnew/*Res*/, rU/*OpA*/, rV/*OpB*/);
484
485 /* Vnew = V^2 mod P */
486 PKA_MOD_MUL( lenId, rVnew/*Res*/, rV/*OpA*/, rV/*OpB*/);
487
488 /* rT = U^2 */
489 PKA_MOD_MUL( lenId, rT/*Res*/, rU/*OpA*/, rU/*OpB*/);
490
491 /* rT= D * U^2 */
492 PKA_MOD_MUL( lenId, rT/*Res*/, rD/*OpA*/, rT/*OpB*/);
493
494 /* Vnew = (V^2 + D*U^2) */
495 PKA_ADD( lenId+1, rVnew/*Res*/, rT/*OpA*/, rVnew/*OpB*/);
496 /* modular division by 2 */
497 PkaModDivideBy2( lenId, rVnew, rP/*mod*/, rVnew);
498
499 /* swap V,Vnew and U,Unew */
500 SWAP_INT8(rVnew,rV);
501 SWAP_INT8(rUnew,rU);
502
503 /* get bit i from register K */
504 bit = PkaGetBitFromPkaReg( rK, lenId, i, rT);
505
506 if (bit != 0) {
507 /* Unew = (U+V)/2 */
508 PKA_ADD( lenId+1, rUnew/*Res*/, rV/*OpA*/, rU/*OpB*/);
509 /* modular division by 2 */
510 PkaModDivideBy2( lenId, rUnew, rP/*mod*/, rUnew);
511
512 /* Vnew = (U*D+V)/2 */
513 PKA_MOD_MUL( lenId, rVnew/*Res*/, rD/*OpA*/, rU/*OpB*/);
514 PKA_ADD( lenId+1, rVnew/*Res*/, rV/*OpA*/, rVnew/*OpB*/);
515 PkaModDivideBy2( lenId, rVnew, rP/*mod*/, rVnew);
516
517 /* swap V,Vnew and U,Unew */
518 SWAP_INT8(rVnew,rV);
519 SWAP_INT8(rUnew,rU);
520
521 }
522 }
523
524 /* U = U mod P */
525 PKA_DIV( lenId+1, rT/*ResNotUsed*/, rU/*OpA*/, rP/*OpB*/);
526
527 // If U is equal to 0 return success code = 1, else 0
528 PKA_COMPARE_IM_STATUS( lenId+1, rU/*OpA*/, 0/*OpB immed*/, status);
529 if (status == 1) {
530 *pSuccessCode = 1;
531 } else {
532 *pSuccessCode = 0;
533 }
534
535
536 return error;
537
538 }
539
540
541 /*********** PkaRsaKgX931FindPrime1 function **********************/
542 /**
543 * @brief Finds a small auxiliary prime (104...176 bits)
544 * for the Key Generation under the X931 standard.
545 *
546 * @return CC_OK On success, otherwise indicates failure
547 */
PkaRsaKgX931FindPrime1(CCRndContext_t * pRndContext,int8_t rP,RsaKgParams_t * rsaKgPrimeTestParams,const int8_t * pRegTemps,uint32_t tempsCount,uint32_t * pTempBuff)548 static CCError_t PkaRsaKgX931FindPrime1(CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
549 int8_t rP, /*!< [in/out] Virtual pointer to the prime buff. */
550 RsaKgParams_t *rsaKgPrimeTestParams, /*!< [in] Pointer to primality testing parameters structure. */
551 const int8_t *pRegTemps, /*!< [in] Pointer to temp PKA registers list (5 single registers). */
552 uint32_t tempsCount, /*!< [in] Count of temp registers in the list. */
553 uint32_t *pTempBuff) /*!< [in] Temp buffer of size 2 max RSA buffer size. */
554 {
555 CCError_t error = CC_OK;
556 uint32_t i, c, d;
557 uint32_t *pTempRem = NULL;
558 uint32_t r;
559 /* the reminder and prime product virtual pointers */
560 int8_t rPrimeProduct;
561 /* temp register */
562 int8_t rT, rT1, rT2;
563 /* the rabin miller success code */
564 int8_t successCode;
565
566 /* check temp registers count */
567 #ifdef LLF_PKI_PKA_DEBUG
568 if (tempsCount < 4)
569 return PKA_NOT_ENOUGH_TEMP_REGS_ERROR;
570 #else
571 tempsCount = tempsCount;
572 #endif
573
574
575 /* allocation of the temp registers */
576 rPrimeProduct = pRegTemps[0];
577 rT = pRegTemps[1];
578 rT1 = pRegTemps[2];
579 rT2 = pRegTemps[3];
580
581
582 /* clearing the extended temp registers */
583 PKA_2CLEAR(LEN_ID_MAX_BITS, rPrimeProduct/*regNum*/);
584 PKA_2CLEAR(LEN_ID_MAX_BITS, rT/*regNum*/);
585
586 /* set the LSB of the prime to insure it is an odd number: rP_ptr[0] |= 1 */
587 PKA_SET_BIT0( LEN_ID_PQ_PKA_REG_BITS/*lenId*/, rP/*Res*/, rP/*OpA*/);
588
589 // calculating the prime reminder
590 pTempRem = &pTempBuff[0];
591 for (i = 0; i < CALC_PRIME_PRODUCT ; ++i) {
592 /* load the current prime product into PKA register */
593 PKA_WRITE_WORD_TO_REG(g_PrimeProduct[i], 0, rPrimeProduct);
594
595 /* copy rP=>rT and calculate the reminder */
596 PKA_COPY(LEN_ID_MAX_BITS, rT/*dest*/, rP/*src*/);
597 PKA_DIV(LEN_ID_PQ_PKA_REG_BITS, rT1/*resNotUsed*/, rT/*OpA*/, rPrimeProduct/*OpB*/);
598
599 /* read result rT word[0] and load it into reminder word[i] */
600 PKA_READ_WORD_FROM_REG(pTempRem[i], 0, rT);
601
602 }/* end of loop for calculating the reminders */
603
604
605 // the main loop for finding a prime
606 for (d = 0; ; d += 2) {
607
608 PKA_2CLEAR(LEN_ID_MAX_BITS, rT/*regNum*/);
609
610 // finding a candidate for a prime
611 for (c = 0, i = 0; i < CALC_PRIME_PRODUCT; ++i) {
612 if (pTempRem[i] + d < d) { /* remark: [*] */
613 pTempRem[i] -= g_PrimeProduct[i];
614 }
615
616 r = pTempRem[i] + d;
617
618 for (; c < g_LastProductPrime[i]; ++c) {
619 if (r % g_SmallPrime[c] == 0)
620 goto Next_d;
621 }
622 }
623
624 /* calculate P = P + d. */
625 /* load d into register rT. Note: rT already cleared, except the LS word */
626 PKA_WRITE_WORD_TO_REG(d, 0, rT);
627 PKA_ADD( LEN_ID_PQ_PKA_REG_BITS, rP/*Res*/, rP/*OpA*/, rT/*OpB*/);
628
629
630 // initialization of modular operations
631 /* copy P into modulus register r0 */
632 if (rP != PKA_REG_N) {
633 PKA_COPY(LEN_ID_MAX_BITS, PKA_REG_N/*dst*/, rP/*src*/);
634 }
635
636 /* initialization of modular operations, the "modulus" in this case is P or Q which is 1/2 modulus size.*
637 * that's the reason we use PQ Len ID */
638 PkaCalcNpIntoPkaReg(LEN_ID_AUX_PRIME_BITS,
639 rsaKgPrimeTestParams->auxPrimesSizeInBits,
640 PKA_REG_N, PKA_REG_NP, rT, rT1);
641
642 // executing the Miller-Rabin test
643 error = PkaRsaKgX931MillerRabinTest(pRndContext,
644 LEN_ID_AUX_PRIME_BITS,
645 rsaKgPrimeTestParams->auxPrimesSizeInBits,
646 &successCode, /*out*/
647 rsaKgPrimeTestParams->auxPrimesMilRabTestsCount, /*in*/
648 rT, rT1, rT2, /*temp registers*/
649 pTempBuff+CALC_PRIME_PRODUCT);
650 if (error != CC_OK) {
651 return error;
652 }
653
654 /* on sucess return CC_OK we have found a prime */
655 if (successCode == CC_TRUE) {
656 return CC_OK;
657 }
658
659 /* update d and reminder to avoid overflow of d (unlikely event) */
660 for (i = 0; i < CALC_PRIME_PRODUCT; ++i) {
661 pTempRem[i] += d; /* remark: since [*] passed, there is no need to recheck */
662 }
663
664 d = 0;
665
666 Next_d:
667 continue;
668
669 }/* end of main loop for finding a prime */
670 }
671
672
673 /*********** PkaRsaKgX931FindPrime2 function **********************/
674 /**
675 * @brief Finds a valid prime2 (second stage prime) for the Key Gen under the X9.31 standard .
676 *
677 * Assumptions : supports a fixed size of 101 bits as required in the standard.
678 *
679 * @return CC_OK On success, otherwise indicates failure
680 */
PkaRsaKgX931FindPrime2(CCRndContext_t * pRndContext,int8_t rP,int8_t rDelta,int8_t rE,uint32_t modulusSizeInBits,RsaKgParams_t * rsaKgPrimeTestParams,const int8_t * pRegTemps,uint32_t tempsCount,uint32_t * pTempBuff)681 static CCError_t PkaRsaKgX931FindPrime2(CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
682 int8_t rP, /*!< [in/out] Virtual pointer to the prime P (P or Q in RSA). */
683 int8_t rDelta, /*!< [in] Virtual pointer to the delta factor. */
684 int8_t rE, /*!< [in] Virtual pointer to public exponent. */
685 uint32_t modulusSizeInBits, /*!< [in] Size of prime to be generated. */
686 RsaKgParams_t *rsaKgPrimeTestParams, /*!< [in] Pointer to primality testing parameters structure. */
687 const int8_t *pRegTemps, /*!< [in] Pointer to temp PKA registers list. */
688 uint32_t tempsCount, /*!< [in] Count of temp registers in the list (6 single registers). */
689 uint32_t *pTempBuff) /*!< [in] Temp buffer of size 2 max RSA buffer size. */
690 {
691 CCError_t error = CC_OK;
692 int8_t successCode;
693 uint32_t i, c;
694 uint32_t status;
695 uint32_t bitVal;
696 uint32_t *pTempRem = NULL;
697 uint32_t *pTempDelta = NULL;
698 /* the reminder and prime product virtual pointers */
699 int8_t rPrimeProduct;
700 /* temp register */
701 int8_t rT, rT1, rT2;
702
703 /* check temp registers count */
704 #ifdef LLF_PKI_PKA_DEBUG
705 if (tempsCount < 4)
706 return PKA_NOT_ENOUGH_TEMP_REGS_ERROR;
707 #endif
708
709
710 /* allocation of the reminder and product on temp registers */
711 rPrimeProduct = pRegTemps[0];
712 rT = pRegTemps[1];
713 rT1 = pRegTemps[2];
714 rT2 = pRegTemps[3];
715
716 // calculating the prime reminder
717 /* clearing the temp registers (extended) */
718 PKA_2CLEAR(LEN_ID_MAX_BITS, rPrimeProduct/*regNum*/);
719 PKA_2CLEAR(LEN_ID_MAX_BITS, rT/*regNum*/);
720
721 // calculate Rdelta and the Reminder
722 /* if the prime candidate P is even add the delta */
723 PKA_READ_BIT0(LEN_ID_PQ_PKA_REG_BITS, rP/*OpA*/, bitVal);
724 if (bitVal == 0) {
725 PKA_ADD( LEN_ID_PQ_PKA_REG_BITS/*lenId*/, rP/*Res*/, rP/*OpA*/, rDelta/*OpB*/);
726 }
727
728 /* multiply delta by 2 */
729 PKA_ADD( LEN_ID_PQ_PKA_REG_BITS/*lenId*/, rDelta/*Res*/, rDelta/*OpA*/, rDelta/*OpB*/);
730
731 // loop for calculating the products
732 pTempRem = &pTempBuff[0];
733 pTempDelta = &pTempBuff[CALC_PRIME_PRODUCT];
734
735 for (i = 0; i < CALC_PRIME_PRODUCT ; ++i) {
736 /* load the current rPrimeProduct[0] = g_PrimeProduct[i] */
737 PKA_WRITE_WORD_TO_REG(g_PrimeProduct[i], 0, rPrimeProduct);
738
739 /* copy rP=>rT and calculate the reminder in reg rT */
740 PKA_COPY(LEN_ID_MAX_BITS, rT/*dest*/, rP/*src*/);
741 PKA_DIV( LEN_ID_PQ_PKA_REG_BITS, rT1/*ResNotUsed*/, rT/*OpA*/, rPrimeProduct/*OpB*/);
742
743 /* load the next word of reminder: rRem[i] = rT[0] */
744 PKA_READ_WORD_FROM_REG(pTempRem[i], 0, rT);
745
746 /* calculate the Rdelta */
747 PKA_COPY(LEN_ID_MAX_BITS, rT/*dest*/, rDelta/*src*/);
748 PKA_DIV( LEN_ID_PQ_PKA_REG_BITS, rT1/*ResNotUsed*/, rT/*OpA*/, rPrimeProduct/*OpB*/);
749
750 /* load the Rdelta with the result rRdeltam[i] = rT[0]*/
751 PKA_READ_WORD_FROM_REG(pTempDelta[i], 0, rT);
752
753 }/* end of loop for calculating the reminders */
754
755 /* main loop for finding the prime */
756 while (1) {
757 //WATCH_DOG_RESET(); // obsolete. Watchdog should be fed by dedicated task
758
759 /* checking if the current prime should be tested */
760 for (c=0 , i=0 ; i < CALC_PRIME_PRODUCT ; i++) {
761 for (; c < g_LastProductPrime[i] ; c++) {
762 if ((pTempRem[i] % g_SmallPrime[c]) == 0) {
763
764 goto NextPrime;
765 }
766 }
767 }
768
769 /* execute rT = GCD(e,P-1) */
770 PKA_SUB_IM( LEN_ID_PQ_PKA_REG_BITS, rT/*Res*/, rP/*OpA*/, 1/*imm*/); /* rP= rP-1 */
771 PKA_COPY(LEN_ID_MAX_BITS, PKA_REG_N/*dest*/, rE/*src*/);
772
773 /* rT = GCD */
774 PKA_MOD_INV( LEN_ID_PQ_BITS, rT1/*Res*/, rT/*OpA*/);
775
776 /* if the GCD != 1, go to the next prime */
777 PKA_COMPARE_IM_STATUS(LEN_ID_PQ_PKA_REG_BITS, rT/*OpA*/, 1/*OpB*/, status);
778 if (status != 1) {
779 goto NextPrime;
780 }
781
782 /* initialization of modular operations for modulus P */
783 /* reset modulus in register r0 = rP */
784 PKA_COPY(LEN_ID_MAX_BITS, PKA_REG_N/*dst*/, rP/*src*/);
785
786 /* initialization of modular operations */
787 PkaCalcNpIntoPkaReg(LEN_ID_PQ_BITS, modulusSizeInBits, PKA_REG_N, PKA_REG_NP, rT, rT1);
788
789
790 /* perform primality tests */
791 /* init lhe test flag to FALSE */
792 successCode = CC_FALSE;
793
794 /* execute the Miller-Rabin test */
795 error = PkaRsaKgX931MillerRabinTest(pRndContext,
796 LEN_ID_PQ_BITS,
797 modulusSizeInBits,
798 &successCode, /*out*/
799 rsaKgPrimeTestParams->pqPrimesMilRabTestsCount, /*count R-M Tests */
800 rT, rT1, rT2, /*temp registers*/
801 pTempBuff+2*CALC_PRIME_PRODUCT);
802 if (error != CC_OK) {
803 goto End; //LR goto ClearAndReturn
804 }
805
806 /* if the previous test succeeded, execute the Lucas test */
807 if (successCode == CC_TRUE) {
808 error = PkaRsaKgX931LucasPrimeTest(
809 LEN_ID_PQ_BITS,
810 &successCode, /*out*/
811 pRegTemps + 3, /*temp registers list*/
812 tempsCount-3);
813 if (error != CC_OK) {
814 goto End; //LR goto ClearAndReturn
815 }
816 }
817
818 /* if both tests are passed, exit - we have finded a prime */
819 if (successCode == CC_TRUE) {
820 return CC_OK;
821 }
822
823 /* finding the next prime candidate */
824 NextPrime:
825
826 /* updating of remainders Rem[i] */
827 for (i = 0 ; i < CALC_PRIME_PRODUCT ; i++) {
828 pTempRem[i] += pTempDelta[i];
829 if (pTempRem[i] < pTempDelta[i]) {
830 pTempRem[i] -= g_PrimeProduct[i];
831 }
832
833 }
834
835 //find new P if previous one isn't correct
836 /* the new prime candidate: P = P + Delta */
837 PKA_ADD(LEN_ID_PQ_PKA_REG_BITS, rP/*Res*/, rP/*OpA*/, rDelta/*OpB*/);
838
839 }/* end of searching for a prime loop */
840
841 End:
842 // RL Check and ddd Clearing temp buffers if need !!!!
843 return error;
844
845 }
846
847 /*********** RsaKgX931FindPrime function **********************/
848 /**
849 * @brief Finds a valid prime for the Key Gen under the X931 standard .
850 *
851 * Assumes: - the PKA is initialized on default mode according to modulusSizeInBits,
852 * - the modulusSizeInBits is set into lenId RegsSizesTable,
853 *
854 * @return CC_OK On success, otherwise indicates failure
855 */
RsaKgX931FindPrime(CCRndContext_t * pRndContext,int8_t rP1,int8_t rP2,int8_t rP,uint32_t modulusSizeInBits,uint32_t rE,RsaKgParams_t * rsaKgPrimeTestParams,const int8_t * pRegTemps,uint32_t tempsCount,uint32_t * pTempBuff)856 static CCError_t RsaKgX931FindPrime(CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
857 int8_t rP1, /*!< [in] Virtual pointers to PKA registers of auxiliary primes p1. */
858 int8_t rP2, /*!< [in] Virtual pointers to PKA registers of auxiliary primes p2. */
859 int8_t rP, /*!< [in/out] Virtual pointer to the register containing P prime. */
860 uint32_t modulusSizeInBits, /*!< [in] Size of the prime P. */
861 uint32_t rE, /*!< [in] Virtual pointer to public exponent. */
862 RsaKgParams_t *rsaKgPrimeTestParams, /*!< [in] Pointer to primality testing parameters structure. */
863 const int8_t *pRegTemps, /*!< [in] Pointer to temp PKA registers list (5 single registers). */
864 uint32_t tempsCount, /*!< [in] Count of temp registers in the list. */
865 uint32_t *pTempBuff) /*!< [in] Pointer to the temp buffer of size 2 max RSA buffer size. */
866 {
867 CCError_t error = CC_OK;
868 uint32_t status, flag;
869 /* virtual pointers to PKA registers */
870 int8_t rP12, rPmodP12, rR1, rR2;
871 /* virtual pointers to temp PKA registers */
872 int8_t rT1;
873
874 /* allocation of registers */
875 rP12 = pRegTemps[0];
876 rPmodP12 = pRegTemps[1];
877 rR1 = pRegTemps[2];
878 rR2 = pRegTemps[3];
879 rT1 = pRegTemps[4];
880
881
882 /* check temp registers count */
883 #ifdef LLF_PKI_PKA_DEBUG
884 if (tempsCount < 5)
885 return PKA_NOT_ENOUGH_TEMP_REGS_ERROR;
886 #endif
887
888 /* find the first primes P1, P2 of size 101 bit */
889 /* p1 */
890 error = PkaRsaKgX931FindPrime1( pRndContext,
891 rP1,
892 rsaKgPrimeTestParams,
893 pRegTemps, tempsCount,
894 pTempBuff);
895 if (error != CC_OK)
896 return error;
897
898 /* p2 */
899 error = PkaRsaKgX931FindPrime1( pRndContext,
900 rP2,
901 rsaKgPrimeTestParams,
902 pRegTemps, tempsCount,
903 pTempBuff);
904 if (error != CC_OK) {
905 return error;
906 }
907
908 /* Debug */
909 #ifdef LLF_PKI_PKA_DEBUG
910 PKA_COPY(LEN_ID_MAX_BITS, rP1/*dst*/, rP1/*src*/);
911 PKA_COPY(LEN_ID_MAX_BITS, rP2/*dst*/, rP2/*src*/);
912 #endif
913
914 /* find P12 = P1*P2 , pModP12 = P mod P12 (operations size from lenId) */
915 /* Note: modulusSizeInBits must be set into lenId entry */
916 /* P12 = P1 * P2 */
917 PKA_MUL_LOW(LEN_ID_PQ_PKA_REG_BITS, rP12/*Res*/, rP1/*OpA*/, rP2/*OpB*/);
918
919 /* PmodP12 = P mod P12 */
920 PKA_COPY(LEN_ID_MAX_BITS, rPmodP12/*dst*/, rP/*src*/);
921 PKA_DIV( LEN_ID_PQ_PKA_REG_BITS, rT1/*ResNotUsed*/, rPmodP12/*OpA*/, rP12/*OpB*/);
922
923
924 /* find; R1= (1/P2 mod P1)*P2 - (1/P1 mod P2)*P1; R2= ... similary .. */
925 /* calculate R1 = (1/P2 mod P1)*P2 */
926 PKA_COPY(LEN_ID_MAX_BITS, PKA_REG_N/*mod reg*/, rP1/*src*/);
927 PKA_2CLEAR(LEN_ID_MAX_BITS, rT1/*dst*/);
928 PKA_COPY(LEN_ID_MAX_BITS, rT1/*dst*/, rP2/*src*/);
929
930 /* if P1 > P2 set flag = 1, else flag = 0 */
931 PKA_SUB(LEN_ID_PQ_PKA_REG_BITS, RES_DISCARD, rP2/*OpA*/, rP1/*OpB*/);
932 PKA_GET_STATUS_CARRY(status);
933 if (status == 0) {
934 flag = 1;
935 } else {
936 /* set rT1 = P2 mod P1 = rT1 - rP1 */
937 flag = 0;
938 PKA_SUB(LEN_ID_PQ_PKA_REG_BITS, rT1/*Res*/, rT1/*OpA*/, rP1/*OpB*/);
939 }
940
941 /* R1 = (1/P2 mod P1) */
942 /* we know PKA_REG_N - rP1 is prime, so we can use ModInv with the odd number*/
943 /* we do not check GCD, since PKA_REG_N is prime and rT1 < PKA_REG_N. therfore GCD must be 1 */
944 PKA_MOD_INV(LEN_ID_PQ_BITS, rR1/*Res*/, rT1/*OpB*/);
945
946 PKA_MUL_LOW( LEN_ID_PQ_PKA_REG_BITS, rR1/*Res*/, rR1/*OpA*/, rP2/*OpB*/);
947
948 /* calculate R2 = (1/P1 mod P2)*P1 */
949 PKA_COPY(LEN_ID_MAX_BITS, PKA_REG_N/*mod reg*/, rP2/*src*/);
950 PKA_2CLEAR(LEN_ID_MAX_BITS, rT1/*dst*/);
951 PKA_COPY(LEN_ID_MAX_BITS, rT1/*dst*/, rP1/*src*/);
952
953 /* if flag == 1, i.e. P2 >= P1, then set rT1 = P1 mod P2 = P1 - P2 */
954 if (flag == 1) {
955 PKA_SUB(LEN_ID_PQ_PKA_REG_BITS, rT1/*Res*/, rT1/*OpA*/, rP2/*OpB*/);
956 }
957
958 /* we know PKA_REG_N = rP2 is prime, so we can use ModInv with the odd number*/
959 PKA_MOD_INV(LEN_ID_PQ_BITS, rR2/*Res*/, rT1/*OpB*/);
960
961 PKA_MUL_LOW( LEN_ID_PQ_PKA_REG_BITS, rR2/*Res*/, rR2/*OpA*/, rP1/*OpB*/);
962
963
964 /* R=R1-R2; if(R <0) R= R+P12; */
965 /* R1 and R2 are max 202 bits each, so LEN_ID_PQ_BITS should be enought to hold negative number*/
966 PKA_SUB(LEN_ID_PQ_PKA_REG_BITS, rR1/*res*/, rR1/*OpA*/, rR2/*OpB*/);
967 PKA_GET_STATUS_CARRY(status);
968 if (status == 0) {
969 PKA_ADD(LEN_ID_PQ_PKA_REG_BITS, rR1/*res*/, rR1/*OpA*/, rP12/*OpB*/);
970 }
971
972 /* R=R-PmodP12; if(R<0) R=R+P12; */
973 PKA_SUB(LEN_ID_PQ_PKA_REG_BITS, rR1/*res*/, rR1/*OpA*/, rPmodP12/*OpB*/);
974 PKA_GET_STATUS_CARRY(status);
975 if (status == 0) {
976 PKA_ADD(LEN_ID_PQ_PKA_REG_BITS, rR1/*res*/, rR1/*OpA*/, rP12/*OpB*/);
977 }
978
979 /* add P = P + R */
980 PKA_ADD(LEN_ID_PQ_PKA_REG_BITS, rP/*res*/, rP/*OpA*/, rR1/*OpB*/);
981
982 //now in rP is a number with new conditions
983
984 /* find the prime P */
985 error = PkaRsaKgX931FindPrime2( pRndContext, rP, rP12/*rDelta*/, rE,
986 modulusSizeInBits,
987 rsaKgPrimeTestParams,
988 pRegTemps + 1, tempsCount-1,
989 pTempBuff);
990
991 return error;
992
993 }
994
995
996 /*********** RsaKgQuickPrimeTest function **********************/
997 /**
998 * @brief Checks primality of big number relating to set of small prime numbers.
999 *
1000 * Notes: - 3 PKA registers used: rP, rModRes, rSmallNum,
1001 * - the PKA must be initialized according tp P size,
1002 * - lenId+1 entry containing the extended register size.
1003 *
1004 * @return CC_OK On success, otherwise indicates failure
1005 */
RsaKgQuickPrimeTest(uint8_t lenId,int8_t rP,int8_t rModRes,int8_t rSmallPrime,int8_t rT,uint32_t divCount)1006 static int32_t RsaKgQuickPrimeTest(uint8_t lenId, /*!< [in] The SizesTable entry, containing the exact P size in bits. */
1007 int8_t rP, /*!< [in] The virtual pointer to big number P register to be checked. */
1008 int8_t rModRes, /*!< [in] Virtual pointers to temp registers. */
1009 int8_t rSmallPrime, /*!< [in] Virtual pointers to temp registers. */
1010 int8_t rT, /*!< [in] Virtual pointers to temp registers. */
1011 uint32_t divCount) /*!< [in] . */
1012 {
1013 uint32_t i;
1014 uint32_t status;
1015
1016 /* set pointer smallPrime_ptr to PKA register low word */
1017 /* clear rSmallPrime register (with extension) */
1018 PKA_2CLEAR(LEN_ID_MAX_BITS, rSmallPrime/*OpA*/);
1019
1020 /* Check primality by dividing P by small primes */
1021 for (i = 0; i < divCount; i++) {
1022 /* copy rP into rModReg for dividing */
1023 PKA_COPY(LEN_ID_MAX_BITS, rModRes/*dst*/, rP/*src*/);
1024
1025 /* set the next small prime into PKA register */
1026 PKA_WRITE_WORD_TO_REG(g_SmallPrime[i], 0, rSmallPrime);
1027
1028 /* calculate remainder: rModReg = rP % smallPrime */
1029 PKA_DIV( lenId+1, rT/*ResNotUsed*/, rModRes/*OpA*/, rSmallPrime/*OpB*/);
1030
1031 /* check is the remainder equaled to 0 by add operation */
1032 PKA_ADD_IM( lenId+1, RES_DISCARD/*discard Res*/, rModRes/*OpA*/, 0/*OpB*/);
1033 PKA_GET_STATUS_ALU_OUT_ZERO(status);
1034 if (status) {
1035 return CC_FALSE;
1036 }
1037 }
1038
1039 return CC_TRUE;
1040 }
1041
1042
1043 /*********** PkaRsaKgFindPrime function **********************/
1044 /**
1045 * @brief Finds a valid prime for the Key Gen.
1046 *
1047 * @return CC_OK On success, otherwise indicates failure
1048 */
PkaRsaKgFindPrime(CCRndContext_t * pRndContext,int8_t rP,uint32_t modulusSizeInBits,int8_t rE,RsaKgParams_t * rsaKgPrimeTestParams,const int8_t * pRegTemps,uint32_t tempsCount,uint32_t * pTempBuff)1049 static CCError_t PkaRsaKgFindPrime(CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
1050 int8_t rP, /*!< [in/out] Virtual pointer to the prime P register. */
1051 uint32_t modulusSizeInBits, /*!< [in] Prime size in bits. */
1052 int8_t rE, /*!< [in] Virtual pointer to the public exponent register. */
1053 RsaKgParams_t *rsaKgPrimeTestParams, /*!< [in] Pointer to primality testing parameters structure. */
1054 const int8_t *pRegTemps, /*!< [in] Pointer to temp PKA registers list. */
1055 uint32_t tempsCount, /*!< [in] Count of temp registers in the list (9). */
1056 uint32_t *pTempBuff) /*!< [in] Temp buffer of size 2 max RSA buffer size. */
1057 {
1058 CCError_t error = CC_OK;
1059 #if !defined RSA_KG_NO_RND
1060 CCRndState_t *rndState_ptr;
1061 #endif
1062 CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
1063 /* virtual pointers to PKA data registers */
1064 int8_t rP1, rP2;
1065
1066 /* temp buffer for auxiliary random number / big end
1067 1E05B8F18D807DB7A47EF53567 nearest random is: 1E 05 B8 F1 8D 80 7D
1068 B7 A4 7E F5 35 99*/
1069 uint32_t rBuff[PKA_RSA_AUX_PRIME_BUFF_SIZE_IN_32BIT_WORDS] = {0};
1070 uint32_t auxPrimeSizeInBytes, auxPrimeSizeInWords;
1071 uint32_t mask, msBit;
1072
1073 if (pRndContext == NULL) {
1074 return CC_RND_CONTEXT_PTR_INVALID_ERROR;
1075 }
1076
1077 #if !defined RSA_KG_NO_RND
1078 rndState_ptr = (CCRndState_t *)(pRndContext->rndState);
1079 #endif
1080 RndGenerateVectFunc = pRndContext->rndGenerateVectFunc;
1081
1082 if (RndGenerateVectFunc == NULL) {
1083 return CC_RND_GEN_VECTOR_FUNC_ERROR;
1084 }
1085
1086 #ifdef LLF_PKI_PKA_DEBUG
1087 if (tempsCount < 9)
1088 return PKA_NOT_ENOUGH_TEMP_REGS_ERROR;
1089 #endif
1090
1091 /* allocate virtual pointers on temp registers */
1092 rP1 = pRegTemps[0];
1093 rP2 = pRegTemps[1];
1094
1095 /* calculate size of aux. primes in bytes and words */
1096 auxPrimeSizeInBytes = CALC_FULL_BYTES(rsaKgPrimeTestParams->auxPrimesSizeInBits);
1097 auxPrimeSizeInWords = CALC_FULL_32BIT_WORDS(rsaKgPrimeTestParams->auxPrimesSizeInBits);
1098
1099 #if defined RSA_KG_NO_RND
1100 #ifdef LLF_PKI_PKA_DEBUG
1101 if (PQindex == 0) {
1102 CC_PalMemCopy( rBuff, rBuff1, auxPrimeSizeInBytes); /*for P*/
1103 } else {
1104 CC_PalMemCopy( rBuff, rBuff3, auxPrimeSizeInBytes); /*for Q*/
1105 }
1106
1107
1108 #ifdef BIG__ENDIAN
1109 CC_COMMON_INVERSE_UINT32_IN_ARRAY(rBuff, auxPrimeSizeInWords);
1110 #endif
1111 #endif
1112
1113 #else
1114 /* get a random auxiliary number P1 */
1115 error = RndGenerateVectFunc((void *)rndState_ptr, (unsigned char*)rBuff, (size_t)auxPrimeSizeInBytes );
1116 if (error != CC_OK) {
1117 return error;
1118 }
1119 #endif
1120
1121 /* calculate mask for aux.prime candidate */
1122 mask = (~0UL >> (32 - (rsaKgPrimeTestParams->auxPrimesSizeInBits & 0x1F)));
1123 msBit = 1UL << ((rsaKgPrimeTestParams->auxPrimesSizeInBits & 0x1F)-1);
1124
1125 /* calculate mask and set MS bit of aux.prime candidate */
1126 rBuff[auxPrimeSizeInWords-1] &= mask;
1127 rBuff[auxPrimeSizeInWords-1] |= msBit;
1128 /* set LSBit = 1 to ensure the odd number */
1129 rBuff[0] |= 1UL;
1130
1131 #ifdef FIPS_CERTIFICATION
1132 primeInt->bitlen1 = rsaKgPrimeTestParams->auxPrimesSizeInBits;
1133 CC_CommonReverseMemcpy(primeInt->xPrime1, (uint8_t*)rBuff, auxPrimeSizeInBytes);
1134 #endif
1135
1136 #ifdef LLF_PKI_PKA_DEBUG
1137 #if (defined RSA_KG_NO_RND || defined RSA_KG_FIND_BAD_RND)
1138 /* set pointers for extern P,Q and aux.primes buffers*/
1139 if (PQindex == 0) {
1140 P1R_ptr = P1pR; P2R_ptr = P2pR;
1141 P1Pr_ptr = P1pPr; P2Pr_ptr = P2pPr;
1142 PQ_ptr = rBuffP;
1143 } else {
1144 P1R_ptr = P1qR; P2R_ptr = P2qR;
1145 P1Pr_ptr = P1qPr; P2Pr_ptr = P2qPr;
1146 PQ_ptr = rBuffQ;
1147 }
1148
1149 CC_PalMemCopy((uint8_t*)P1R_ptr, (uint8_t*)rBuff, auxPrimeSizeInBytes); /*for P*/ //xp1
1150
1151 #endif
1152 #endif
1153
1154 /* copy random number into PKA register rP1 */
1155 PkaCopyDataIntoPkaReg( rP1/*dstReg*/, LEN_ID_MAX_BITS, rBuff/*src_ptr*/, auxPrimeSizeInWords);
1156
1157 #ifdef RSA_KG_NO_RND
1158 #ifdef LLF_PKI_PKA_DEBUG
1159 CC_PalMemSetZero(rBuff, sizeof(rBuff));
1160 if (PQindex == 0) {
1161 CC_PalMemCopy( rBuff, rBuff2, auxPrimeSizeInBytes); /*for P*/
1162 } else {
1163 CC_PalMemCopy( rBuff, rBuff4, auxPrimeSizeInBytes); /*for Q*/
1164 }
1165
1166 #ifdef BIG__ENDIAN
1167 CC_COMMON_INVERSE_UINT32_IN_ARRAY( rBuff, auxPrimeSizeInWords );
1168 #endif
1169 #endif
1170
1171 #else
1172
1173 /* get a random auxiliary number P2 */
1174 CC_PalMemSetZero(rBuff, sizeof(rBuff));
1175 error = RndGenerateVectFunc((void *)rndState_ptr, (unsigned char *)rBuff, (size_t)auxPrimeSizeInBytes );
1176 if (error != CC_OK) {
1177 return error;
1178 }
1179
1180 #endif
1181 /* set MS bit of P2*/
1182 rBuff[auxPrimeSizeInWords-1] &= mask;
1183 rBuff[auxPrimeSizeInWords-1] |= msBit;
1184 /* set LSBit = 1 to ensure the odd number */
1185 rBuff[0] |= 1UL;
1186
1187 #ifdef FIPS_CERTIFICATION
1188 primeInt->bitlen2 = rsaKgPrimeTestParams->auxPrimesSizeInBits;
1189 CC_CommonReverseMemcpy(primeInt->xPrime2, (uint8_t*)rBuff, auxPrimeSizeInBytes);
1190 #endif
1191 /* Debug */
1192 #ifdef LLF_PKI_PKA_DEBUG
1193 #if defined RSA_KG_FIND_BAD_RND
1194 CC_PalMemCopy( (uint8_t*)P2R_ptr, (uint8_t*)rBuff, auxPrimeSizeInBytes); /*for P*/ //xp2
1195 #endif
1196 #endif
1197
1198 /* copy random number P2 into PKA register rP2 */
1199 PkaCopyDataIntoPkaReg( rP2/*dstReg*/, LEN_ID_MAX_BITS, rBuff/*src_ptr*/, auxPrimeSizeInWords);
1200
1201 //at the end of this function rP includes P value
1202 /* find the primes P1,P2, P */
1203 error = RsaKgX931FindPrime(pRndContext,
1204 rP1, rP2, /*aux.primes*/
1205 rP, /*prime*/
1206 modulusSizeInBits,
1207 rE, /*exp*/
1208 rsaKgPrimeTestParams,
1209 pRegTemps + 2, tempsCount-2,
1210 pTempBuff);
1211
1212 /* Debug */
1213 #ifdef LLF_PKI_PKA_DEBUG
1214 #if (defined RSA_KG_NO_RND || defined RSA_KG_FIND_BAD_RND)
1215 /* save found results: rP1,rP2,rP for P and Q accordingly */
1216 PkaCopyDataFromPkaReg( P1Pr_ptr/*dst_ptr*/, auxPrimeSizeInWords, rP1/*srcReg*/);
1217
1218 PkaCopyDataFromPkaReg( P2Pr_ptr/*dst_ptr*/, auxPrimeSizeInWords, rP2/*srcReg*/);
1219
1220 PkaCopyDataFromPkaReg( PQ_ptr/*dst_ptr*/, modulusSizeInBits/32, rP/*srcReg*/);
1221 #endif
1222 #endif
1223
1224 return error;
1225
1226 }
1227
1228
1229 /*********** RsaKgPrimeTest function **********************/
1230 /**
1231 * @brief Performs assigned count of Rabin-Miller tests and one Lucas-Lehmer
1232 * test according to testing mode:
1233 * - for RSA according to ANSI X9.31 standard.
1234 * - for DH according to ANSI X9.42 standard.
1235 *
1236 * NOTE: For using in RSA module size of each temp buffer must be of minimum size
1237 * of prime number P in words.
1238 * For using in ANSI X9.42 standard (DH,DSA algorithms) size of each temp buffer
1239 * must be minimum of two size of prime number P in words.
1240 *
1241 * @return CC_OK On success, otherwise indicates failure
1242 */
RsaKgPrimeTest(CCRndContext_t * pRndContext,uint32_t * pPrimeP,int32_t sizeWords,int32_t rabinTestsCount,int8_t * pIsPrime,CCRsaDhPrimeTestMode_t primeTestMode,uint32_t * pTempBuff)1243 static CCError_t RsaKgPrimeTest(CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
1244 uint32_t *pPrimeP, /*!< [in] Pointer to the prime buff. */
1245 int32_t sizeWords, /*!< [in] Prime size in words. */
1246 int32_t rabinTestsCount, /*!< [in] Count of Rabin-Miller tests repetition. */
1247 int8_t *pIsPrime, /*!< [in] The flag indicates primality: not prime - CC_FALSE, otherwise - CC_TRUE. */
1248 CCRsaDhPrimeTestMode_t primeTestMode, /*!< [in] Primality testing mode (RSA or DH - defines how are performed some
1249 operations on temp buffers. */
1250 uint32_t *pTempBuff) /*!< [in] Temp buffer of size 3*ModSizeWords. */
1251 {
1252 CCError_t error = CC_OK;
1253 uint32_t modulusSizeInBits;
1254 uint32_t divCount;
1255 uint32_t pkaReqRegs = 11;
1256
1257 /* virtual pointers to PKA regs*/
1258 /* set registers pointers, note: r0=PKA_REG_N, r1=PKA_REG_NP by default reserved for N and NP */
1259 uint8_t rT2 = regTemps[2];
1260 uint8_t rT3 = regTemps[3];
1261 uint8_t rT4 = regTemps[4]; /* temp registers */
1262
1263 /* exact size of P */
1264 modulusSizeInBits = CC_BITS_IN_32BIT_WORD * sizeWords;
1265
1266 /* initialize the PKA engine on default mode with size of registers */
1267 /* according to operation size = max(Asize,Bsize) */
1268 error = PkiCalcNp(pTempBuff, pPrimeP, modulusSizeInBits);
1269 if (error != CC_OK) {
1270 return error;
1271 }
1272
1273 error = PkaInitAndMutexLock(modulusSizeInBits, &pkaReqRegs);
1274 if (error != CC_OK) {
1275 return error;
1276 }
1277
1278 /* set modulus into PKA register r0 */
1279 PkaCopyDataIntoPkaReg( PKA_REG_N/*dstReg*/, LEN_ID_MAX_BITS/*lenId*/, pPrimeP/*src_ptr*/, sizeWords);
1280
1281 /* copy Np to PKA register #1*/
1282 PkaCopyDataIntoPkaReg( PKA_REG_NP/*dstReg*/, LEN_ID_MAX_BITS/*lenId*/, pTempBuff/*src_ptr*/,
1283 CC_PKA_BARRETT_MOD_TAG_BUFF_SIZE_IN_WORDS);
1284
1285 /* execute primality tests */
1286 /* count of small primes (each one is DxUint16) to check:
1287 - for DH algorithm use predefined value,
1288 else use maximal value */
1289
1290 if (primeTestMode == CC_DH_PRIME_TEST_MODE) {
1291 divCount = RSA_QUICK_PRIME_TEST_DIVISIONS_COUNT;
1292 } else {
1293 divCount = sizeof(g_SmallPrime) / sizeof(uint16_t);
1294 }
1295
1296 /* test by small prime numbers */
1297 *pIsPrime = (int8_t)RsaKgQuickPrimeTest(
1298 LEN_ID_N_BITS/*lenId*/,
1299 PKA_REG_N /*prime P*/,
1300 rT2, rT3, rT4/*temp regs*/,
1301 divCount);
1302
1303 /* the Miller-Rabin test */
1304 if (*pIsPrime == CC_TRUE) {
1305 error = PkaRsaKgX931MillerRabinTest(pRndContext,
1306 LEN_ID_N_BITS /*lenId*/,
1307 modulusSizeInBits,
1308 pIsPrime, /*out*/
1309 rabinTestsCount,
1310 rT2, rT3, rT4/*temp regs*/,
1311 pTempBuff);
1312 if (error != CC_OK) {
1313 goto End;
1314 }
1315 }
1316
1317 /* the Lucas test */
1318 if (*pIsPrime == CC_TRUE) {
1319 error = PkaRsaKgX931LucasPrimeTest(
1320 LEN_ID_N_BITS /*lenId*/,
1321 pIsPrime, /*out*/
1322 regTemps+2,
1323 7 /*tempsCount*/);
1324 }
1325 End:
1326 PkaFinishAndMutexUnlock(pkaReqRegs);
1327
1328 return error;
1329
1330 }
1331
1332
1333 /*********** RsaCalculateNandD function **********************/
1334 /**
1335 * @brief Calculates RSA modulus and private key in NonCRT mode.
1336 *
1337 * @return CC_OK On success, otherwise indicates failure
1338 */
RsaCalculateNandD(CCRsaPubKey_t * pCcPubKey,CCRsaPrivKey_t * pCcPrivKey,CCRsaKgData_t * pKeyGenData,uint32_t primeSizeInBits)1339 CCError_t RsaCalculateNandD(CCRsaPubKey_t *pCcPubKey, /*!< [in] pointer to the public key structure */
1340 CCRsaPrivKey_t *pCcPrivKey, /*!< [in] pointer to the private key structure */
1341 CCRsaKgData_t *pKeyGenData, /*!< [in] pointer to a structure required for the KeyGen operation, holding P and Q */
1342 uint32_t primeSizeInBits) /*!< [in] Size of the prime factors in bits. */
1343 {
1344 uint32_t primeSizeInWords, i;
1345 uint32_t pkaRegsCount = 8;
1346 CCError_t error=CC_OK;
1347 /* define virtual pointers to PKA registers */
1348 uint32_t r0 = PKA_REG_N; /*mod*/
1349 uint32_t rLcm = 1;
1350 uint32_t rP = 2;
1351 uint32_t rQ = 3;
1352 uint32_t rD = 4;
1353 uint32_t rT = 5;
1354 uint32_t *pPrivExp = pCcPrivKey->PriveKeyDb.NonCrt.d;
1355
1356
1357 /* setting the primes P,Q length in bytes */
1358 primeSizeInWords = CALC_FULL_32BIT_WORDS(primeSizeInBits);
1359 /*Mutex lock and PKA init*/
1360 error = PkaInitAndMutexLock(2*primeSizeInBits, &pkaRegsCount );
1361 if (error != CC_SUCCESS) {
1362 return error;
1363 }
1364 /* RL clean the n-buffer */
1365 CC_PalMemSetZero( pCcPubKey->n, CC_32BIT_WORD_SIZE*CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS );
1366
1367 PkaSetLenIds(primeSizeInBits, LEN_ID_PQ_BITS);
1368 PkaSetLenIds(GET_FULL_OP_SIZE_BITS(primeSizeInBits), LEN_ID_PQ_PKA_REG_BITS);
1369
1370 /* clear pka memory for new using */
1371 PkaClearBlockOfRegs(r0/*firstReg*/, pkaRegsCount, LEN_ID_MAX_BITS);
1372
1373
1374 /* copy P, Q into PKA registers. Note: now size of registers is full. */
1375 PkaCopyDataIntoPkaReg(rP/*dstReg*/, LEN_ID_MAX_BITS, pKeyGenData->KGData.p/*src_ptr*/,
1376 primeSizeInWords);
1377
1378 PkaCopyDataIntoPkaReg(rQ/*dstReg*/, LEN_ID_MAX_BITS, pKeyGenData->KGData.q/*src_ptr*/,
1379 primeSizeInWords);
1380
1381 /*******************************************************************************************/
1382 /* CALCULATIONS WITH LONG REGISTERS */
1383 /* Init the PKA again on default mode according to N operation size. */
1384 /* Note: All PKA memory shall be cleaned, nSizeInBits=> entry 0, nSizeInBits+CC_PKA_WORD_SIZE_IN_BITS=> entry 1 */
1385 /*******************************************************************************************/
1386 /* N= r0= P*Q. lenId = 0 for full reg size */
1387 PKA_MUL_LOW(LEN_ID_N_BITS, r0, rP/*OpA*/, rQ/*OpB*/); // use LEN_ID_N_BITS, since its size is 2*primeSizeInBits
1388
1389 /* output the modulus N */
1390 PkaCopyDataFromPkaReg(pCcPubKey->n, 2*primeSizeInWords, r0/*srcReg*/);
1391 CC_PalMemCopy(pCcPrivKey->n, pCcPubKey->n, pCcPubKey->nSizeInBits / CC_BITS_IN_BYTE);
1392
1393 if (pCcPrivKey->OperationMode == CC_RSA_NoCrt) {
1394 bool isTrue = false;
1395 uint32_t stat;
1396 uint32_t rGcd;
1397 uint32_t bit0P, bit0Q;
1398
1399
1400 /* calculate D = E^-1 mod LCM(P-1)*(Q-1) */
1401 PKA_FLIP_BIT0(LEN_ID_N_BITS, rP/*Res*/, rP/*OpA*/);
1402 PKA_FLIP_BIT0(LEN_ID_N_BITS, rQ/*Res*/, rQ/*OpA*/);
1403
1404 /* remove common factors 2 from P-1, Q-1 to find odd */
1405 i = 0;
1406 do {
1407 PKA_SHR_FILL0(LEN_ID_N_BITS, rP, rP, 0/*shift-1*/);
1408 PKA_SHR_FILL0(LEN_ID_N_BITS, rQ, rQ, 0/*shift-1*/);
1409 PKA_READ_BIT0(LEN_ID_N_BITS, rP, bit0P);
1410 PKA_READ_BIT0(LEN_ID_N_BITS, rQ, bit0Q);
1411 i++;
1412 } while (bit0P == 0 && bit0Q == 0);
1413
1414
1415 /* D = (P-1) * (Q-1) / 2^i (removed only common divider 2^i) */
1416 PKA_2CLEAR(LEN_ID_MAX_BITS, rD); // ? RL
1417 PKA_MUL_LOW(LEN_ID_N_BITS, rD/*Res*/, rP/*OpA*/, rQ/*OpB*/);
1418 PKA_SHL_FILL0(LEN_ID_N_BITS, rD, rD, i-1);
1419
1420 /* chose odd number as modulus for ModInv operation */
1421 if (bit0P == 1) {
1422 PKA_COPY(LEN_ID_N_BITS, r0/*dst*/, rP);
1423 rGcd = rQ;
1424 } else {
1425 PKA_COPY(LEN_ID_N_BITS, r0/*dst*/, rQ);
1426 rGcd = rP;
1427 }
1428
1429 /* calculate GCD(rP,rQ) */
1430 PKA_MOD_INV(LEN_ID_N_BITS, rT/*temp*/, rGcd);
1431 /* LCM = ((P-1)*(Q-1) / GCD) = rD/rGcd */
1432 PKA_DIV(LEN_ID_N_BITS, rLcm/*res: LCM*/, rD, rGcd);
1433
1434
1435 // Because LCM may be even, but HW ModInw operation works only with odd modulus,
1436 // we use reverse calculation as follows: D = 1/E mod LCM = LCM - ((1/LCM mod E)*LCM - 1) / E
1437
1438 /* copy public exp E into r0 register */
1439 PkaCopyDataIntoPkaReg(r0/*dstReg*/, LEN_ID_MAX_BITS, pCcPubKey->e/*src_ptr*/,
1440 CALC_FULL_32BIT_WORDS(pCcPubKey->eSizeInBits));
1441
1442 /* calc rT = 1/LCM mod E */
1443 PKA_COPY(LEN_ID_N_BITS, rP/*dst*/, rLcm/*LCM*/); /*rP used as temp*/
1444 PKA_DIV(LEN_ID_N_BITS, rQ/*Res not used*/, rP/*OpA=LCM*/, r0/*OpB=E*/); /*rP = LCM mod E*/
1445
1446 PKA_MOD_INV(LEN_ID_N_BITS, rT/*Res*/, rP/*OpB*/); /* rT = 1/LCM mod E (E - odd, gcd(LCM,E)=1) */
1447 /* RL additional check need if E is not prime */
1448 PKA_COMPARE_IM_STATUS(LEN_ID_N_BITS, rP, 1/*im*/, stat);
1449 if (stat != 1) {
1450 error = PKA_INTERNAL_ERROR;
1451 goto End;
1452 }
1453
1454 /* rK = (rT*LCM - 1) / r0=E */
1455 PKA_MUL_LOW(LEN_ID_N_PKA_REG_BITS, rT/*Res*/, rT/*OpA*/, rLcm/*OpB*/); /* Note: size of result < register size, because E is small */
1456 PKA_SUB_IM(LEN_ID_N_PKA_REG_BITS, rT/*Res*/, rT/*OpA*/, 1/*OpB*/);
1457 PKA_DIV(LEN_ID_N_PKA_REG_BITS, rD/*Res*/, rT/*OpA*/, r0/*OpB*/); /*rT = rT / e*/
1458 PKA_SUB(LEN_ID_N_PKA_REG_BITS, rD/*Res*/, rLcm/*OpA*/, rD/*OpB*/);
1459
1460 /* output the result value D */
1461 PkaCopyDataFromPkaReg(pPrivExp, 2*primeSizeInWords, rD/*srcReg*/);
1462
1463 /* check that d > 2^(nlen/2) [FIPS 186-4, B.3.1] - very rare *
1464 * case. */
1465 for (i = 2*primeSizeInWords - 1; i >= primeSizeInWords; i--) {
1466 isTrue = isTrue || (pPrivExp[i] != 0);
1467 }
1468 if (!isTrue) {
1469 CC_PalMemSetZero(pPrivExp, 2*primeSizeInWords);
1470 error = CC_RSA_GENERATED_PRIV_KEY_IS_TOO_LOW;
1471 }
1472
1473 /* set the length of d in bits */
1474 pCcPrivKey->PriveKeyDb.NonCrt.dSizeInBits =
1475 CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.NonCrt.d,
1476 (uint16_t)(CALC_FULL_32BIT_WORDS(pCcPubKey->nSizeInBits)));
1477 }
1478
1479 End:
1480
1481 PkaFinishAndMutexUnlock( pkaRegsCount );
1482
1483 return error;
1484 }
1485
1486
1487 /*********** RsaKgFindPrime function **********************/
1488 /**
1489 * @brief The RsaKgFindPrime generates a prime for RSA keys.
1490 *
1491 * @return CC_OK On success, otherwise indicates failure
1492 */
RsaKgFindPrime(CCRndContext_t * pRndContext,uint32_t * pPubExp,uint32_t eSizeInBits,uint32_t nSizeInBits,uint32_t * pSuccess,uint32_t * pPrime,uint32_t * pTempBuff)1493 static CCError_t RsaKgFindPrime(
1494 CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
1495 uint32_t *pPubExp, /*!< [in] Pointer to the public exponent. */
1496 uint32_t eSizeInBits, /*!< [in/out] Size of public exponent in bits. */
1497 uint32_t nSizeInBits, /*!< [in/out] Required size of the key in bits. */
1498 uint32_t *pSuccess, /*!< [out] Pointer to the flag of success generation of P,Q.*/
1499 uint32_t *pPrime, /*!< [out] Pointer to the first factor - P. */
1500 uint32_t *pTempBuff) /*!< [out] Temp buffer for internal use. */
1501 {
1502 CCError_t error=CC_OK;
1503 uint32_t primeSizeInBits, primeSizeInWords;
1504 RsaKgParams_t rsaKgPrimeTestParams;
1505 /* virtual pointers to PKA registers of single size */
1506 int8_t rE, rP;
1507 /* virtual pointers to single temp PKA registers */
1508 uint32_t status, maxCountRegs = 20;
1509
1510 // setting the primes P,Q length ; Note: the size of the modulus n is even
1511 primeSizeInBits = nSizeInBits / 2;
1512 primeSizeInWords = CALC_FULL_32BIT_WORDS(primeSizeInBits);
1513
1514 /*Initialize PKA and mutex lock*/
1515 error = PkaInitAndMutexLock(primeSizeInBits, &maxCountRegs);
1516 if (error != CC_SUCCESS) {
1517 return error;
1518 }
1519
1520 *pSuccess = CC_FALSE;
1521
1522 // set virtual registers pointers
1523 rE =regTemps[2]; /*2*/
1524 rP =regTemps[3]; /*3*/
1525
1526 /* Set size if P, Q and auxiliary primes p1,p2,q1,q2 according *
1527 * to keysize. The following settings meet to FIPS 186-4: *
1528 * 5.1, C.3: Tab.C3. */
1529 if (nSizeInBits <= CC_RSA_FIPS_KEY_SIZE_1024_BITS) {
1530 rsaKgPrimeTestParams.auxPrimesSizeInBits = PKA_RSA_KEY_1024_AUX_PRIME_SIZE_BITS;
1531 rsaKgPrimeTestParams.auxPrimesMilRabTestsCount = PKA_RSA_KEY_1024_AUX_PRIME_RM_TST_COUNT /*38*/;
1532 rsaKgPrimeTestParams.pqPrimesMilRabTestsCount = PKA_RSA_KEY_1024_PQ_PRIME_RM_TST_COUNT /* 7*/;
1533 } else if (nSizeInBits <= CC_RSA_FIPS_KEY_SIZE_2048_BITS) {
1534 rsaKgPrimeTestParams.auxPrimesSizeInBits = PKA_RSA_KEY_2048_AUX_PRIME_SIZE_BITS;
1535 rsaKgPrimeTestParams.auxPrimesMilRabTestsCount = PKA_RSA_KEY_2048_AUX_PRIME_RM_TST_COUNT /*32*/;
1536 rsaKgPrimeTestParams.pqPrimesMilRabTestsCount = PKA_RSA_KEY_2048_PQ_PRIME_RM_TST_COUNT /* 4*/;
1537 } else {/* if key size > 2048 */
1538 rsaKgPrimeTestParams.auxPrimesSizeInBits = PKA_RSA_KEY_3072_AUX_PRIME_SIZE_BITS;
1539 rsaKgPrimeTestParams.auxPrimesMilRabTestsCount = PKA_RSA_KEY_3072_AUX_PRIME_RM_TST_COUNT /*27*/;
1540 rsaKgPrimeTestParams.pqPrimesMilRabTestsCount = PKA_RSA_KEY_3072_PQ_PRIME_RM_TST_COUNT /* 3*/;
1541 }
1542
1543 /**********************************************************************************/
1544 /* CALCULATIONS WITH SHORT REGISTERS */
1545 /* init PKA on default mode according to P,Q operation size for creating P and Q. */
1546 /* Note: All PKA memory shall be cleaned, insert nSizeInBits/2 => entry 0, */
1547 /* nSizeInBits/2+CC_PKA_WORD_SIZE_IN_BITS => entry 1 */
1548 /**********************************************************************************/
1549
1550 /* set additional sizes into RegsSizesTable: */
1551 PkaSetLenIds(nSizeInBits/2, LEN_ID_PQ_BITS);
1552 PkaSetLenIds(GET_FULL_OP_SIZE_BITS(nSizeInBits/2), LEN_ID_PQ_PKA_REG_BITS);
1553 PkaSetLenIds(rsaKgPrimeTestParams.auxPrimesSizeInBits, LEN_ID_AUX_PRIME_BITS);
1554
1555 /* inforcing the prime candidates P,Q so the size of they is keySize/2 */
1556 pPrime[primeSizeInWords - 1] |= 0x80000000;
1557 pPrime[primeSizeInWords] = 0;
1558 pPrime[0] |= 0x01;
1559 #ifdef FIPS_CERTIFICATION
1560 CC_CommonReverseMemcpy(primeInt->xPrime, (uint8_t *)pPrime, primeSizeInBits/CC_BITS_IN_BYTE);
1561 #endif
1562
1563 /* copy P,E buffers into PKA registers */
1564 PkaCopyDataIntoPkaReg(rP/*dstReg*/, LEN_ID_MAX_BITS, pPrime/*src_ptr*/, primeSizeInWords);
1565 PkaCopyDataIntoPkaReg(rE/*dstReg*/, LEN_ID_MAX_BITS, pPubExp/*src_ptr*/, CALC_FULL_32BIT_WORDS(eSizeInBits));
1566
1567 /* find the prime vector */
1568 error = PkaRsaKgFindPrime( pRndContext, rP, primeSizeInBits,
1569 rE,
1570 &rsaKgPrimeTestParams,
1571 regTemps+5, maxCountRegs-5/*tempsCount*/,
1572 pTempBuff);
1573
1574
1575 if (error != CC_OK) {
1576 goto End;
1577 }
1578
1579 /* temp for debug */
1580 #if defined LLF_PKI_PKA_DEBUG && defined DEBUG
1581 #if (defined RSA_KG_NO_RND || defined RSA_KG_FIND_BAD_RND)
1582 PQindex = 1;
1583 #endif
1584 #endif
1585
1586 PkaCopyDataFromPkaReg( pPrime/*dst_ptr*/, primeSizeInWords, rP/*srcReg*/ );
1587
1588 /* Because now we use only a prime e it's enough to check that (p-1) / e has a residue.
1589 * Divide: rE = (public exponent) mod (generated prime)
1590 * NOTE: if e generated as random odd number - it is required to test that GCD(e,p-1)=1, instead of divison*/
1591 PKA_SUB_IM(LEN_ID_MAX_BITS, rP, rP, 1);
1592 PKA_DIV(LEN_ID_MAX_BITS, RES_DISCARD/*Res not used*/, rP/*OpA*/, rE/*OpB*/);
1593 PKA_COMPARE_IM_STATUS(LEN_ID_MAX_BITS, rP/*(p-1) mod e*/, 0, status)
1594
1595 if (status == 0){ //if rP==0 than status =1
1596 *pSuccess = CC_TRUE;
1597 }
1598
1599 End:
1600 /* Finish PKA operations (waiting PKI done and close PKA clocks) */
1601 PkaFinishAndMutexUnlock(maxCountRegs);
1602
1603 return error;
1604
1605
1606 }
1607
1608
1609
1610 /*********** RsaCalculateCrtParams function **********************/
1611 /**
1612 * @brief Calculates a private key on CRT mode
1613 *
1614 * @return CC_OK On success, otherwise indicates failure
1615 */
RsaCalculateCrtParams(uint32_t * pPubExp,uint32_t eSizeInBits,uint32_t nSizeInBits,uint32_t * pPrimeP,uint32_t * pPrimeQ,uint32_t * pPrivExp1dp,uint32_t * pPrivExp2dq,uint32_t * pQInv)1616 CCError_t RsaCalculateCrtParams(uint32_t *pPubExp, /*!< [in] Pointer to the public exponent. */
1617 uint32_t eSizeInBits, /*!< [in] Public exponent size in bits. */
1618 uint32_t nSizeInBits, /*!< [in] Size of the key modulus in bits. */
1619 uint32_t *pPrimeP, /*!< [out] First factor pointer - p. */
1620 uint32_t *pPrimeQ, /*!< [out] Second factor pointer - Q. */
1621 uint32_t *pPrivExp1dp, /*!< [out] Private exponent for first factor - dP. */
1622 uint32_t *pPrivExp2dq, /*!< [out] Private exponent for second factor - dQ. */
1623 uint32_t *pQInv) /*!< [out] The modular inverse of q relatively to modulus p - qInv. */
1624 {
1625 CCError_t error=CC_OK;
1626 uint32_t primeSizeInWords;
1627 /* virtual pointers to PKA registers of single size */
1628 int8_t r0, rP, rdP, rQ, rdQ, rQinv, rE;
1629 /* virtual pointers to single temp PKA registers */
1630 int8_t rT1, rT2, rT3, rT4, rT5;
1631 uint32_t maxCountRegs = 15;
1632
1633 /* setting the primes P,Q length ; Note: the size of the modulus n is even */
1634 primeSizeInWords = CALC_FULL_32BIT_WORDS(nSizeInBits/2);
1635
1636 error = PkaInitAndMutexLock(primeSizeInWords*CC_BITS_IN_32BIT_WORD, &maxCountRegs );
1637 if (error != CC_SUCCESS) {
1638 return error;
1639 }
1640
1641 // set virtual registers pointers
1642 r0 = regTemps[0]; /* PKA_REG_N */
1643 rE = regTemps[2]; /*2*/
1644 rP = regTemps[3]; /*3*/
1645 rQ = regTemps[4]; /*4*/
1646 rdP = regTemps[5]; /*5*/
1647 rdQ = regTemps[6]; /*6*/
1648 rQinv = regTemps[7]; /*7*/
1649 rT1 = regTemps[8]; /*8*/
1650 rT2 = regTemps[9]; /*9*/
1651 rT3 = regTemps[10]; /*10*/
1652 rT4 = regTemps[11]; /*11*/
1653 rT5 = regTemps[12]; /*12*/
1654
1655 // copy data into PKA registers
1656 PkaCopyDataIntoPkaReg(rE/*dstReg*/, LEN_ID_MAX_BITS, pPubExp/*src_ptr*/, CALC_FULL_32BIT_WORDS(eSizeInBits));
1657 PkaCopyDataIntoPkaReg(rP/*dstReg*/, LEN_ID_MAX_BITS, pPrimeP/*src_ptr*/, primeSizeInWords);
1658 PkaCopyDataIntoPkaReg(rQ/*dstReg*/, LEN_ID_MAX_BITS, pPrimeQ/*src_ptr*/, primeSizeInWords);
1659
1660 // dQ = E^-1 mod (Q-1);
1661 // dQ: set mod register r0=Q-1 and perform ModInv operation
1662 PKA_FLIP_BIT0(LEN_ID_N_PKA_REG_BITS, r0/*res*/, rQ/*opA*/);
1663 PKA_COPY(LEN_ID_MAX_BITS, rT1/*ds*/, rE/*src*/);
1664 error = PkaExecFullModInv( rT1/*OpB*/, rdQ/*Res*/, rT2, rT3, rT4, rT5);
1665 if (error != CC_OK) {
1666 goto End;
1667 }
1668
1669
1670 // dP = E^-1 mod (P-1);
1671 // dP: set mod register r0<=P-1 and perform ModInv operation
1672 PKA_FLIP_BIT0(LEN_ID_N_PKA_REG_BITS, r0/*res*/, rP/*dst*/);
1673 PKA_COPY(LEN_ID_MAX_BITS, rT1/*ds*/, rE/*src*/);
1674 error = PkaExecFullModInv( rT1/*OpB*/, rdP/*Res*/, rT2, rT3, rT4, rT5);
1675 if (error != CC_OK) {
1676 goto End;
1677 }
1678
1679 // qInv = Q^-1 mod P;
1680 // Qinv: set mod register r0<=P and perform ModInv operation
1681 PKA_FLIP_BIT0(LEN_ID_N_PKA_REG_BITS, r0/*Res*/, r0/*OpA*/); /* r0= P */
1682 PKA_COPY(LEN_ID_MAX_BITS, rT1/*dst*/, rQ/*src*/);
1683 PKA_MOD_INV(LEN_ID_N_BITS, rQinv/*Res*/, rT1/*OpB*/);
1684
1685
1686 // output of the result values dP,dQ,qInv
1687 PkaCopyDataFromPkaReg(pPrivExp1dp, primeSizeInWords, rdP/*srcReg*/);
1688 PkaCopyDataFromPkaReg(pPrivExp2dq, primeSizeInWords, rdQ/*srcReg*/);
1689 PkaCopyDataFromPkaReg(pQInv, primeSizeInWords, rQinv/*srcReg*/);
1690 End:
1691 PkaFinishAndMutexUnlock(maxCountRegs);
1692 return error;
1693
1694 }
1695
1696
1697
1698
1699
1700
1701 /*********** RsaPrimeTestCall function **********************/
1702 /**
1703 * @brief Test a primality according to ANSI X9.42 standard by
1704 * calling the RsaKgPrimeTest() which performs said algorithm.
1705 *
1706 * @return CC_OK On success, otherwise indicates failure
1707 */
RsaPrimeTestCall(CCRndContext_t * pRndContext,uint32_t * pPrimeP,int32_t sizeWords,int32_t rabinTestsCount,int8_t * pIsPrime,uint32_t * pTempBuff,CCRsaDhPrimeTestMode_t primeTestMode)1708 CCError_t RsaPrimeTestCall(CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
1709 uint32_t *pPrimeP, /*!< [in] The pointer to the prime buff. */
1710 int32_t sizeWords, /*!< [in] The prime size in words. */
1711 int32_t rabinTestsCount, /*!< [in] The count of Rabin-Miller tests repetition. */
1712 int8_t *pIsPrime, /*!< [in] TThe flag indicates primality:
1713 if is not prime - CC_FALSE, otherwise - CC_TRUE. */
1714 uint32_t *pTempBuff, /*!< [in] The temp buffer of minimum size:
1715 - on HW platform 3*MaxModSizeWords,
1716 - on SW platform 41*MaxModSizeWords. */
1717 CCRsaDhPrimeTestMode_t primeTestMode)/*!< [in] primality testing mode (RSA or DH - defines how are performed some
1718 operations on temp buffers. */
1719 {
1720 CCError_t error;
1721
1722 error = RsaKgPrimeTest(
1723 pRndContext,
1724 pPrimeP,
1725 sizeWords,
1726 rabinTestsCount,
1727 pIsPrime,
1728 primeTestMode,
1729 pTempBuff);
1730
1731
1732 return error;
1733
1734 }
1735
1736
1737 /*********** RsaGenPandQ function **********************/
1738 /**
1739 * @brief Generates P and Q primes for RSA key
1740 *
1741 * @return CC_OK On success, otherwise indicates failure
1742 */
RsaGenPandQ(CCRndContext_t * pRndContext,size_t KeySize,uint32_t eSizeInBits,uint32_t * pPubExp,CCRsaKgData_t * pKeyGenData)1743 CCError_t RsaGenPandQ(
1744 CCRndContext_t *pRndContext, /*!< [in/out] Pointer to the RND context buffer. */
1745 size_t KeySize, /* key size in bits */
1746 uint32_t eSizeInBits,
1747 uint32_t *pPubExp,
1748 CCRsaKgData_t *pKeyGenData) /*!< [in] Temporary buffer for internal use. */
1749 {
1750
1751 /* the error identifier */
1752 CCError_t error = CC_OK;
1753
1754 uint32_t *pPrimeP, *pPrimeQ;
1755 uint32_t pqSizeWords;
1756 uint32_t success = 0;
1757 #if ((!defined RSA_KG_FIND_BAD_RND && !defined RSA_KG_NO_RND) || defined RSA_KG_FIND_BAD_RND || !defined DEBUG)
1758 uint32_t buffXp[4]; //buffer for 4 MSB words of Xq
1759 #endif
1760 uint32_t distPQ , tempSwap, i;
1761 CCCommonCmpCounter_t cmpRes;
1762
1763 pPrimeP = pKeyGenData->KGData.p;
1764 pPrimeQ = pKeyGenData->KGData.q;
1765 pqSizeWords = CALC_FULL_32BIT_WORDS(KeySize/2);
1766 #if (defined RSA_KG_FIND_BAD_RND && defined DEBUG)
1767 CC_PalMemCopy( RSA_KG_debugPvect, (uint8_t*)pKeyGenData->KGData.p, KeySize/(2*CC_BITS_IN_BYTE) );
1768 CC_PalMemCopy( RSA_KG_debugQvect, (uint8_t*)pKeyGenData->KGData.q, KeySize/(2*CC_BITS_IN_BYTE) );
1769 #endif
1770
1771 #if (defined RSA_KG_NO_RND && defined DEBUG)
1772 CC_PalMemCopy( (uint8_t*)pKeyGenData->KGData.p, RSA_KG_debugPvect, KeySize/(2*CC_BITS_IN_BYTE) );
1773 CC_PalMemCopy( (uint8_t*)pKeyGenData->KGData.q, RSA_KG_debugQvect, KeySize/(2*CC_BITS_IN_BYTE) );
1774 #endif
1775 #if ((defined RSA_KG_FIND_BAD_RND || defined RSA_KG_NO_RND) && defined DEBUG)
1776 #ifdef BIG__ENDIAN
1777 /* for big endiannes machine reverse bytes order in words according to Big Endian */
1778 CC_COMMON_INVERSE_UINT32_IN_ARRAY( pKeyGenData->KGData.p, KeySize/(2*CC_BITS_IN_32BIT_WORD) );
1779 CC_COMMON_INVERSE_UINT32_IN_ARRAY( pKeyGenData->KGData.q, KeySize/(2*CC_BITS_IN_32BIT_WORD) );
1780 #endif
1781 #endif
1782
1783
1784
1785 /* ................ Generate the 1st prime ................................. */
1786 /* ------------------------------------------------------------------------- */
1787 do{
1788 /* clean the word adjacent to the old P (in case there's garbage in it) */
1789 pPrimeP[pqSizeWords]=0;
1790
1791 /*Generate Xp*/
1792 #if ((!defined RSA_KG_FIND_BAD_RND && !defined RSA_KG_NO_RND) || defined RSA_KG_FIND_BAD_RND || !defined DEBUG)
1793 error = CC_RsaGenerateVectorInRangeX931(pRndContext, pqSizeWords, pPrimeP);
1794 if (error != CC_OK){
1795 goto End;
1796 }
1797
1798 /*save 4 MSB of Xp to temporary buffer for checking it's distance from Xq*/
1799 CC_PalMemCopy(buffXp, pPrimeP, 4 *CC_32BIT_WORD_SIZE );
1800
1801 #ifdef FIPS_CERTIFICATION
1802 rsaKgOutParams.pP_PrimeInt = &prim1Int;
1803 rsaKgOutParams.pQ_PrimeInt = &prim2Int;
1804 primeInt = &prim1Int;
1805 #endif
1806
1807 #endif
1808 /* for debug */
1809 #if (defined RSA_KG_FIND_BAD_RND && defined DEBUG)
1810 CC_PalMemCopy( RSA_KG_debugPvect, (uint8_t*)pPrimeP, KeySize/(2*CC_BITS_IN_BYTE) );
1811 CC_PalMemCopy( RSA_KG_debugQvect, (uint8_t*)pPrimeQ, KeySize/(2*CC_BITS_IN_BYTE) );
1812 #endif
1813 #if ((defined RSA_KG_FIND_BAD_RND || defined RSA_KG_NO_RND) && defined DEBUG)
1814 #ifdef BIG__ENDIAN
1815 /* for big endiannes machine reverse bytes order in words according to Big Endian */
1816 CC_COMMON_INVERSE_UINT32_IN_ARRAY( pPrimeP, KeySize/(2*CC_BITS_IN_32BIT_WORD) );
1817 CC_COMMON_INVERSE_UINT32_IN_ARRAY( pPrimeQ, KeySize/(2*CC_BITS_IN_32BIT_WORD) );
1818 #endif
1819 #if defined LLF_PKI_PKA_DEBUG
1820 PQindex = 0;
1821 #endif
1822 #endif
1823 /*Generate P:*/
1824
1825 error = RsaKgFindPrime(
1826 pRndContext,
1827 pPubExp, eSizeInBits,
1828 KeySize,
1829 &success,
1830 pPrimeP,
1831 pKeyGenData->KGData.kg_buf.ccRSAKGDataIntBuff);
1832 if (error != CC_OK){
1833 goto End;
1834 }
1835
1836 }while(!success); /* End of loop for generating P */
1837
1838 /* ................ Generate the 2nd prime ................................. */
1839 /* ------------------------------------------------------------------------- */
1840 while(1){
1841 /* clean the word adjacent to the old Q (in case there's garbage in it) */
1842 pPrimeQ[pqSizeWords]=0;
1843
1844 #if ((!defined RSA_KG_FIND_BAD_RND && !defined RSA_KG_NO_RND) || defined RSA_KG_FIND_BAD_RND || !defined DEBUG)
1845 while(1){/*Generate Xq*/
1846 error = CC_RsaGenerateVectorInRangeX931(pRndContext, pqSizeWords, pPrimeQ); /*Xq Generation*/
1847 if (error != CC_OK){
1848 goto End;
1849 }
1850
1851 /*check |Xp - Xq|<= 2^(keySize/2-100):
1852 * compare 100 MS bits (3 words + 4 bits) of XP and XQ if they are equall, then
1853 * generate new Xq*/
1854 distPQ = (buffXp[3] - pPrimeQ[pqSizeWords-1]) != 0 ||
1855 (buffXp[2] - pPrimeQ[pqSizeWords-2]) != 0 ||
1856 (buffXp[1] - pPrimeQ[pqSizeWords-3]) != 0 ||
1857 ((buffXp[0] - pPrimeQ[pqSizeWords-4]) & 0xF0000000) != 0;
1858 if (distPQ)
1859 {
1860 break;
1861 }
1862 } /* Generation of Xq is done - pPrimeQ points to Xq */
1863 #endif
1864
1865 /*Generate Q*/
1866 #if defined LLF_PKI_PKA_DEBUG && defined DEBUG
1867 #if (defined RSA_KG_NO_RND || defined RSA_KG_FIND_BAD_RND)
1868 PQindex = 1;
1869 #endif
1870 #endif
1871 #ifdef FIPS_CERTIFICATION
1872 primeInt = &prim2Int;
1873 #endif
1874 error = RsaKgFindPrime(
1875 pRndContext,
1876 pPubExp, eSizeInBits,
1877 KeySize,
1878 &success,
1879 pPrimeQ,
1880 pKeyGenData->KGData.kg_buf.ccRSAKGDataIntBuff);
1881 if (error != CC_OK){
1882 goto End;
1883 }
1884
1885
1886 if(success)
1887 {
1888 distPQ = (pPrimeP[3] - pPrimeQ[pqSizeWords-1]) != 0 ||
1889 (pPrimeP[2] - pPrimeQ[pqSizeWords-2]) != 0 ||
1890 (pPrimeP[1] - pPrimeQ[pqSizeWords-3]) != 0 ||
1891 ((pPrimeP[0] - pPrimeQ[pqSizeWords-4]) & 0xF0000000) != 0;
1892
1893 if (distPQ){
1894 break;
1895 }
1896 else {
1897 /* In case the distance between P and Q is too small, generate a new prime.
1898 * The smaller prime should be discarded and generated again.
1899 * If Q is larger then P set P=Q. */
1900
1901 cmpRes = CC_CommonCmpLsWordsUnsignedCounters(pPrimeP,pqSizeWords,pPrimeQ,pqSizeWords);
1902 if (cmpRes != CC_COMMON_CmpCounter1GreaterThenCounter2) { /* if Q > P */
1903 CC_PalMemCopy(pPrimeP/*dest*/, pPrimeQ/*src*/, pqSizeWords*CC_32BIT_WORD_SIZE);
1904 #ifdef FIPS_CERTIFICATION
1905 rsaKgOutParams.pP_PrimeInt = &prim2Int;
1906 rsaKgOutParams.pQ_PrimeInt = &prim1Int;
1907 #endif
1908 }
1909 }
1910 }
1911 }/* End of loop for generating Q - pPrimeQ points to Q */
1912
1913 /* if Q is larger then P exchange the vectors - we want to have P > Q */
1914 /* copy P,Q, buffers into PKA registers */
1915 cmpRes = CC_CommonCmpLsWordsUnsignedCounters(pPrimeP, pqSizeWords, pPrimeQ, pqSizeWords);
1916
1917 if (cmpRes != CC_COMMON_CmpCounter1GreaterThenCounter2) { /* Q > P */
1918 /* swap P/Q */
1919 for(i=0 ; i<pqSizeWords ; i++){
1920 tempSwap = pKeyGenData->KGData.p[i];
1921 pKeyGenData->KGData.p[i] = pKeyGenData->KGData.q[i];
1922 pKeyGenData->KGData.q[i] = tempSwap;
1923 }
1924
1925 #ifdef FIPS_CERTIFICATION
1926 rsaKgOutParams.pP_PrimeInt = &prim2Int;
1927 rsaKgOutParams.pQ_PrimeInt = &prim1Int;
1928 #endif
1929 }
1930
1931 #if (defined LLF_PKI_PKA_DEBUG || defined RSA_KG_FIND_BAD_RND || !defined DEBUG)
1932 End:
1933 #endif
1934 return error;
1935 }
1936
1937 #endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
1938