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 Files ****************/
14 #include "cc_pal_mem.h"
15 #include "cc_common.h"
16 #include "cc_rsa_error.h"
17 #include "cc_rsa_local.h"
18 #include "cc_common_math.h"
19 #include "cc_rnd_error.h"
20 #include "cc_rsa_kg.h"
21 #include "rsa.h"
22 #include "rsa_public.h"
23 #include "rsa_private.h"
24 #include "cc_general_defs.h"
25 #include "cc_fips_defs.h"
26 #include "cc_pal_mutex.h"
27 #include "cc_pal_abort.h"
28 #ifdef CC_SOFT_KEYGEN
29 #include "ccsw_rsa_kg.h"
30 #endif
31 /************************ Defines ******************************/
32
33 /************************ Enums ************************************/
34
35 /************************ Typedefs *********************************/
36
37 /************************ Global Data ******************************/
38 #ifdef FIPS_CERTIFICATION
39 extern rsaKgInternalDataStruct_t rsaKgOutParams;
40 #endif
41 /************* Private function prototype **************************/
42
43 /************************ Public Functions ******************************/
44
KGCheckAndSetParamsRSA(CCRndContext_t * rndContext_ptr,uint8_t * PubExp_ptr,size_t PubExpSizeInBytes,size_t KeySize,CCRsaUserPrivKey_t * pCcUserPrivKey,CCRsaUserPubKey_t * pCcUserPubKey,CCRsaKgData_t * KeyGenData_ptr)45 static CCError_t KGCheckAndSetParamsRSA(
46 CCRndContext_t *rndContext_ptr,
47 uint8_t *PubExp_ptr,
48 size_t PubExpSizeInBytes,
49 size_t KeySize,
50 CCRsaUserPrivKey_t *pCcUserPrivKey,
51 CCRsaUserPubKey_t *pCcUserPubKey,
52 CCRsaKgData_t *KeyGenData_ptr ){
53
54 /* the error identifier */
55 CCError_t Error = CC_OK;
56 /* the pointers to the key structures */
57 CCRsaPubKey_t *pCcPubKey;
58 CCRsaPrivKey_t *pCcPrivKey;
59
60 CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
61 /* ...... checking the random context pointer ........................ */
62 if (rndContext_ptr == NULL)
63 return CC_RND_CONTEXT_PTR_INVALID_ERROR;
64
65 /* ...... checking the random generate vector function pointer ....... */
66 if (rndContext_ptr->rndGenerateVectFunc == NULL)
67 return CC_RND_GEN_VECTOR_FUNC_ERROR;
68
69 /* ...... checking the key database handle pointer .................. */
70 if (PubExp_ptr == NULL)
71 return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
72
73 /* ...... checking the validity of the exponent pointer ............. */
74 if (pCcUserPrivKey == NULL)
75 return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
76
77 /* ...... checking the validity of the modulus pointer .............. */
78 if (pCcUserPubKey == NULL)
79 return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
80
81 /* ...... checking the validity of the keygen data .................. */
82 if (KeyGenData_ptr == NULL)
83 return CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID;
84
85 /* ...... checking the exponent size .................. */
86 if (PubExpSizeInBytes > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
87 return CC_RSA_INVALID_EXPONENT_SIZE;
88
89 /* ...... checking the required key size ............................ */
90 if (( KeySize < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
91 ( KeySize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
92 ( KeySize % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS )) {
93 return CC_RSA_INVALID_MODULUS_SIZE;
94 }
95
96 /* set the public and private key structure pointers */
97 pCcPubKey = (CCRsaPubKey_t*)pCcUserPubKey->PublicKeyDbBuff;
98 pCcPrivKey = (CCRsaPrivKey_t*)pCcUserPrivKey->PrivateKeyDbBuff;
99
100
101 /* ................ clear all input structures ............................. */
102 /* ------------------------------------------------------------------------- */
103
104 CC_PalMemSetZero(pCcUserPrivKey, sizeof(CCRsaUserPrivKey_t));
105 CC_PalMemSetZero(pCcUserPubKey, sizeof(CCRsaUserPubKey_t));
106 CC_PalMemSetZero(KeyGenData_ptr, sizeof(CCRsaKgData_t));
107
108 /* ................ loading the public exponent to the structure .......... */
109 /* ------------------------------------------------------------------------- */
110
111 /* loading the buffers to start from LS word to MS word */
112 Error = CC_CommonConvertMsbLsbBytesToLswMswWords(
113 pCcPubKey->e, sizeof(pCcPubKey->e),
114 PubExp_ptr, PubExpSizeInBytes);
115 if (Error != CC_OK) {
116 Error = CC_RSA_INVALID_EXPONENT_VAL;
117 goto End;
118 }
119
120 /* .......... initializing the effective counters size in bits .......... */
121 pCcPubKey->eSizeInBits = CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPubKey->e, (PubExpSizeInBytes+3)/4);
122
123 /* if the size in bits is 0 - return error */
124 if (pCcPubKey->eSizeInBits == 0 || pCcPubKey->eSizeInBits > 17) { /* MV - check if needed*/
125 Error = CC_RSA_INVALID_EXPONENT_SIZE;
126 goto End;
127 }
128
129 /* verifing the exponent has legal value (currently only 0x3,0x11 and 0x10001) */
130 /* verifying the exponent has legal value (currently only 0x3,0x11 and 0x10001) */
131 if (pCcPubKey->e[0] != CC_RSA_KG_PUB_EXP_ALLOW_VAL_1 &&
132 pCcPubKey->e[0] != CC_RSA_KG_PUB_EXP_ALLOW_VAL_2 &&
133 pCcPubKey->e[0] != CC_RSA_KG_PUB_EXP_ALLOW_VAL_3) {
134 Error = CC_RSA_INVALID_EXPONENT_VAL;
135 goto End;
136 }
137
138 /* .......... initializing the key sizes ......................... */
139
140 /* this initialization is required for the low level function (LLF) - indicates the required
141 * size of the key to be found */
142 pCcPubKey->nSizeInBits = KeySize;
143 pCcPrivKey->nSizeInBits = KeySize;
144
145 End:
146 return Error;
147 }
148
149 /***********************************************************************************************/
150 #ifndef _INTERNAL_CC_NO_RSA_KG_SUPPORT
151 /**
152 @brief CC_RsaKgKeyPairGenerate generates a Pair of public and private keys on non CRT mode.
153
154 Note: FIPS 186-4 [5.1] standard specifies three choices for the length of the RSA
155 keys (modules): 1024, 2048 and 3072 bits and public exponent value >= 0x10001.
156 This implementation allows to generate keys also with other (not FIPS approved)
157 sizes on the user's responcibility.
158
159 @param [in/out] rndContext_ptr - Pointer to the RND context buffer.
160 @param [in] PubExp_ptr - The pointer to the public exponent (public key).
161 Allowed values 0x3, 0x11, 0x10001.
162 @param [in] PubExpSizeInBytes - The public exponent size in bytes.
163 @param [in] KeySize - The size of the key in bits. Supported sizes are 256 bit multiples
164 between 512 - 4096;
165 @param [out] pCcUserPrivKey - A pointer to the private key structure.
166 This structure is used as input to the CC_RsaPrimDecrypt API.
167 @param [out] pCcUserPubKey - A pointer to the public key structure.
168 This structure is used as input to the CC_RsaPrimEncrypt API.
169 @param [in] KeyGenData_ptr - a pointer to a structure required for the KeyGen operation.
170
171 @return CCError_t - CC_OK,
172 CC_RSA_INVALID_EXPONENT_POINTER_ERROR,
173 CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
174 CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR,
175 CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID,
176 CC_RSA_INVALID_MODULUS_SIZE,
177 CC_RSA_INVALID_EXPONENT_SIZE
178 */
CC_RsaKgKeyPairGenerate(CCRndContext_t * rndContext_ptr,uint8_t * PubExp_ptr,size_t PubExpSizeInBytes,size_t KeySize,CCRsaUserPrivKey_t * pCcUserPrivKey,CCRsaUserPubKey_t * pCcUserPubKey,CCRsaKgData_t * KeyGenData_ptr,CCRsaKgFipsContext_t * pFipsCtx)179 CEXPORT_C CCError_t CC_RsaKgKeyPairGenerate(
180 CCRndContext_t *rndContext_ptr,
181 uint8_t *PubExp_ptr,
182 size_t PubExpSizeInBytes,
183 size_t KeySize,
184 CCRsaUserPrivKey_t *pCcUserPrivKey,
185 CCRsaUserPubKey_t *pCcUserPubKey,
186 CCRsaKgData_t *KeyGenData_ptr,
187 CCRsaKgFipsContext_t *pFipsCtx)
188 {
189 /* LOCAL INITIALIZATIONS AND DECLERATIONS */
190
191 /* the error identifier */
192 CCError_t error = CC_OK;
193
194 /* the pointers to the key structures */
195 CCRsaPubKey_t *pCcPubKey;
196 CCRsaPrivKey_t *pCcPrivKey;
197
198 error = KGCheckAndSetParamsRSA( rndContext_ptr,
199 PubExp_ptr,
200 PubExpSizeInBytes,
201 KeySize,
202 pCcUserPrivKey,
203 pCcUserPubKey,
204 KeyGenData_ptr );
205 if (error != CC_OK){
206 return error;
207 }
208
209 /* set the public and private key structure pointers */
210 pCcPubKey = ( CCRsaPubKey_t *)pCcUserPubKey->PublicKeyDbBuff;
211 pCcPrivKey = ( CCRsaPrivKey_t *)pCcUserPrivKey->PrivateKeyDbBuff;
212
213 /* .......... initialize the public key on the private structure ............... */
214 CC_PalMemCopy(pCcPrivKey->PriveKeyDb.NonCrt.e, pCcPubKey->e, ROUNDUP_BYTES_TO_32BIT_WORD(PubExpSizeInBytes));
215 pCcPrivKey->PriveKeyDb.NonCrt.eSizeInBits = pCcPubKey->eSizeInBits;
216
217 /* .......... set the private mode to non CRT .............................. */
218 /* ------------------------------------------------------------------------- */
219
220 /* set the mode to non CRT */
221 pCcPrivKey->OperationMode = CC_RSA_NoCrt;
222
223 /* ................ executing the key generation ........................... */
224 /* ------------------------------------------------------------------------- */
225 /* ................ execute the low level key gen .......................... */
226 do{
227 error = RsaGenPandQ(
228 rndContext_ptr, /*!< [in/out] Pointer to the RND context buffer. */
229 KeySize,
230 pCcPubKey->eSizeInBits,
231 pCcPubKey->e,
232 KeyGenData_ptr);
233 if (error != CC_OK) {
234 goto End;
235 }
236
237
238 /* calculate modulus n and private exponent d */
239 error = RsaCalculateNandD(
240 pCcPubKey,
241 pCcPrivKey,
242 KeyGenData_ptr,
243 KeySize/2);
244
245 if (error != CC_RSA_GENERATED_PRIV_KEY_IS_TOO_LOW && error != CC_OK) { \
246 goto End;
247 }
248 }while(error!=CC_OK);
249
250 #ifdef FIPS_CERTIFICATION
251 CC_CommonReverseMemcpy(rsaKgOutParams.nModulus, (uint8_t*)pCcPubKey->n, KeySize/CC_BITS_IN_BYTE);
252 CC_CommonReverseMemcpy(rsaKgOutParams.pPrim, (uint8_t*)KeyGenData_ptr->KGData.p, KeySize/(2*CC_BITS_IN_BYTE));
253 CC_CommonReverseMemcpy(rsaKgOutParams.qPrim, (uint8_t*)KeyGenData_ptr->KGData.q, KeySize/(2*CC_BITS_IN_BYTE));
254 CC_CommonReverseMemcpy(rsaKgOutParams.dPrivExponent, (uint8_t*)pCcPrivKey->PriveKeyDb.NonCrt.d, KeySize/CC_BITS_IN_BYTE);
255 #endif
256
257
258
259 /* ................ initialize the low level key structures ................ */
260 /* ------------------------------------------------------------------------- */
261
262 error = RsaInitPubKeyDb( pCcPubKey );
263 if (error != CC_OK) {
264 goto End;
265 }
266
267 error = RsaInitPrivKeyDb( pCcPrivKey );
268 if (error != CC_OK) {
269 goto End;
270 }
271
272 /* ................ set the key valid tags ................................. */
273 /* ------------------------------------------------------------------------- */
274 pCcUserPrivKey->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
275 pCcUserPubKey->valid_tag = CC_RSA_PUB_KEY_VALIDATION_TAG;
276
277 // run conditional test
278 error = FIPS_RSA_VALIDATE(rndContext_ptr,pCcUserPrivKey,pCcUserPubKey,pFipsCtx);
279
280
281 End:
282 /* on failure clear the generated key */
283 if (error != CC_OK) {
284 error = CC_RSA_INTERNAL_ERROR;
285 CC_PalMemSetZero((uint8_t*)pCcUserPrivKey, sizeof(CCRsaUserPrivKey_t) );
286 CC_PalMemSetZero((uint8_t*)pCcUserPubKey, sizeof(CCRsaUserPubKey_t) );
287 }
288 if (pFipsCtx != NULL) {
289 CC_PalMemSetZero((uint8_t*)pFipsCtx, sizeof(CCRsaKgFipsContext_t));
290 }
291 /* clear the KG data structure */
292 CC_PalMemSetZero ((uint8_t*)KeyGenData_ptr ,sizeof(CCRsaKgData_t) );
293
294 return error;
295
296
297 }/* END OF CC_RsaKgKeyPairGenerate */
298
299
300 /***********************************************************************************************/
301 /**
302 @brief CC_RsaKgKeyPairCrtGenerate generates a Pair of public and private keys on CRT mode.
303
304 Note: FIPS 186-4 [5.1] standard specifies three choices for the length of the RSA
305 keys (modules): 1024, 2048 and 3072 bits. This implementation allows
306 generate also some other (not FIPS approved) sizes on the user's responcibility.
307
308 @param [in/out] rndContext_ptr - Pointer to the RND context buffer.
309 @param [in] PubExp_ptr - The pointer to the public exponent (public key)
310 @param [in] PubExpSizeInBytes - The public exponent size in bits.
311 @param [in] KeySize - The size of the key in bits. Supported sizes are 256 bit multiples
312 between 512 - 4096;
313 @param [out] pCcUserPrivKey - A pointer to the private key structure.
314 This structure is used as input to the CC_RsaPrimDecrypt API.
315 @param [out] pCcUserPubKey - A pointer to the public key structure.
316 This structure is used as input to the CC_RsaPrimEncrypt API.
317 @param [in] KeyGenData_ptr - a pointer to a structure required for the KeyGen operation.
318
319 @return CCError_t - CC_OK,
320 CC_RSA_INVALID_EXPONENT_POINTER_ERROR,
321 CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
322 CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR,
323 CC_RSA_KEY_GEN_DATA_STRUCT_POINTER_INVALID,
324 CC_RSA_INVALID_MODULUS_SIZE,
325 CC_RSA_INVALID_EXPONENT_SIZE
326 */
327
CC_RsaKgKeyPairCrtGenerate(CCRndContext_t * rndContext_ptr,uint8_t * PubExp_ptr,size_t PubExpSizeInBytes,size_t KeySize,CCRsaUserPrivKey_t * pCcUserPrivKey,CCRsaUserPubKey_t * pCcUserPubKey,CCRsaKgData_t * KeyGenData_ptr,CCRsaKgFipsContext_t * pFipsCtx)328 CEXPORT_C CCError_t CC_RsaKgKeyPairCrtGenerate(
329 CCRndContext_t *rndContext_ptr,
330 uint8_t *PubExp_ptr,
331 size_t PubExpSizeInBytes,
332 size_t KeySize,
333 CCRsaUserPrivKey_t *pCcUserPrivKey,
334 CCRsaUserPubKey_t *pCcUserPubKey,
335 CCRsaKgData_t *KeyGenData_ptr,
336 CCRsaKgFipsContext_t *pFipsCtx )
337 {
338 /* LOCAL INITIALIZATIONS AND DECLERATIONS */
339
340 /* the error identifier */
341 CCError_t Error = CC_OK;
342
343 /* the pointers to the key structures */
344 CCRsaPubKey_t *pCcPubKey;
345 CCRsaPrivKey_t *pCcPrivKey;
346 uint16_t pSizeWords;
347
348 Error = KGCheckAndSetParamsRSA( rndContext_ptr,
349 PubExp_ptr,
350 PubExpSizeInBytes,
351 KeySize,
352 pCcUserPrivKey,
353 pCcUserPubKey,
354 KeyGenData_ptr );
355 if (Error != CC_OK){
356 return Error;
357 }
358 /* set the public and private key structure pointers */
359 pCcPubKey = (CCRsaPubKey_t*)pCcUserPubKey->PublicKeyDbBuff;
360 pCcPrivKey = (CCRsaPrivKey_t*)pCcUserPrivKey->PrivateKeyDbBuff;
361
362 /* .......... initializing the key sizes ......................... */
363 pSizeWords =(uint16_t) KeySize / (2*CC_BITS_IN_32BIT_WORD); // RL
364
365 /* .......... set the private mode to CRT .................................. */
366 /* ------------------------------------------------------------------------- */
367
368 /* set the mode to CRT */
369 pCcPrivKey->OperationMode = CC_RSA_Crt;
370
371
372 /* ................ executing the key generation ........................... */
373 /* ------------------------------------------------------------------------- */
374
375 /* ................ execute the low level key gen ........................... */
376
377 /*Generate P and Q*/
378 Error = RsaGenPandQ(
379 rndContext_ptr,
380 KeySize,
381 pCcPubKey->eSizeInBits,
382 pCcPubKey->e,
383 KeyGenData_ptr);
384
385 /* on failure exit the function */
386 if (Error != CC_OK) {
387 goto End;
388 }
389
390 /* Calculate CRT private Key parameters*/
391 /* calculate modulus n */
392 Error = RsaCalculateNandD(
393 pCcPubKey,
394 pCcPrivKey,
395 KeyGenData_ptr,
396 KeySize/2);
397 /* on failure exit the function */
398 if (Error != CC_OK) {
399 goto End;
400 }
401
402 Error = RsaCalculateCrtParams(
403 pCcPubKey->e, pCcPubKey->eSizeInBits,
404 KeySize,
405 KeyGenData_ptr->KGData.p, KeyGenData_ptr->KGData.q,
406 pCcPrivKey->PriveKeyDb.Crt.dP,
407 pCcPrivKey->PriveKeyDb.Crt.dQ,
408 pCcPrivKey->PriveKeyDb.Crt.qInv);
409
410 if (Error !=CC_OK) {
411 goto End;
412 }
413
414 #ifdef FIPS_CERTIFICATION
415 CC_CommonReverseMemcpy(rsaKgOutParams.nModulus, (uint8_t*)pCcPubKey->n, KeySize/CC_BITS_IN_BYTE);
416 CC_CommonReverseMemcpy(rsaKgOutParams.pPrim, (uint8_t*)KeyGenData_ptr->KGData.p,KeySize/(2*CC_BITS_IN_BYTE));
417 CC_CommonReverseMemcpy(rsaKgOutParams.qPrim, (uint8_t*)KeyGenData_ptr->KGData.q, KeySize/(2*CC_BITS_IN_BYTE));
418 CC_CommonReverseMemcpy(rsaKgOutParams.dPrivExponent, NULL, KeySize/CC_BITS_IN_BYTE);
419 #endif
420
421 /* ................ Set private and public key data ........................ */
422 /* ------------------------------------------------------------------------- */
423 /* Load P,Q vectors */
424 CC_PalMemCopy(pCcPrivKey->PriveKeyDb.Crt.P, KeyGenData_ptr->KGData.p, pCcPubKey->nSizeInBits / 16);
425 CC_PalMemCopy(pCcPrivKey->PriveKeyDb.Crt.Q, KeyGenData_ptr->KGData.q, pCcPubKey->nSizeInBits / 16);
426
427
428 /* ................ set the vector sizes ................................... */
429 /* ------------------------------------------------------------------------- */
430
431 pCcPrivKey->PriveKeyDb.Crt.PSizeInBits =
432 CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.Crt.P, (uint16_t)pSizeWords);
433
434 pCcPrivKey->PriveKeyDb.Crt.QSizeInBits =
435 CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.Crt.Q, (uint16_t)pSizeWords);
436
437 pCcPrivKey->PriveKeyDb.Crt.dPSizeInBits =
438 CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.Crt.dP, (uint16_t)pSizeWords);
439
440 pCcPrivKey->PriveKeyDb.Crt.dQSizeInBits =
441 CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.Crt.dQ, (uint16_t)pSizeWords);
442
443 pCcPrivKey->PriveKeyDb.Crt.qInvSizeInBits =
444 CC_CommonGetWordsCounterEffectiveSizeInBits(pCcPrivKey->PriveKeyDb.Crt.qInv, (uint16_t)pSizeWords);
445
446 /* ................ initialize the low level key structures ................ */
447 /* ------------------------------------------------------------------------- */
448
449 Error = RsaInitPubKeyDb(pCcPubKey);
450 if (Error != CC_OK) {
451 goto End;
452 }
453
454 Error = RsaInitPrivKeyDb(pCcPrivKey);
455 if (Error != CC_OK) {
456 goto End;
457 }
458
459 pCcUserPrivKey->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
460 pCcUserPubKey->valid_tag = CC_RSA_PUB_KEY_VALIDATION_TAG;
461
462 /* run conditional test */
463 Error = FIPS_RSA_VALIDATE(rndContext_ptr,pCcUserPrivKey,pCcUserPubKey,pFipsCtx);
464
465 End:
466
467 /* on failure clear the generated key */
468 if (Error != CC_OK) {
469 Error = CC_RSA_INTERNAL_ERROR;
470 CC_PalMemSetZero(pCcUserPrivKey, sizeof(CCRsaUserPrivKey_t) );
471 CC_PalMemSetZero(pCcUserPubKey, sizeof(CCRsaUserPubKey_t) );
472 }
473 if (pFipsCtx != NULL) {
474 CC_PalMemSetZero(pFipsCtx, sizeof(CCRsaKgFipsContext_t));
475 }
476 /* clear the KG data structure */
477 CC_PalMemSetZero (KeyGenData_ptr ,sizeof(CCRsaKgData_t) );
478
479 return Error;
480
481
482 }/* END OF CC_RsaKgKeyPairCrtGenerate */
483
484
485
486 /**********************************************************************************************************/
487 /**
488 * @brief The CC_RsaGenerateVectorInRangeX931 function generates a random vector in range:
489 * MinVect < RandVect < MaxVect, where:
490 * MinVect = squareRoot(2) * 2^(RndSizeInBits-1), MaxVect = 2^RndSizeInBits.
491 *
492 * Note: 1. MSBit of RandVect must be set to 1.
493 * 2. Words order of output vector is set from LS word to MS
494 * word.
495 *
496 * This function is used in PKI RSA for random generation according to ANS X9.31 standard.
497 * If PKI_RSA is not supported, the function does nothing.
498 *
499 * Functions algorithm::
500 *
501 * 1. Calls the CC_RndGenerateVector() function for generating random vector
502 * RndVect of size RndSizeInWords, rounded up to bytes. Set index i
503 * to high word i = SizeInWords-1.
504 * 2. Check and adust candidate for msWord inside the random vector
505 * starting from msWord himselv, if msWord > high word of MinVect,
506 * goto step 3, else try next word i--; if no words to try, then goto
507 * step 1.
508 * 3. Set the found msWord to high position in array and generate new
509 * random words instead all checked and rejected words.
510 *
511 * @param[in/out] rndContext_ptr - Pointer to the RND context buffer.
512 * @rndSizeWords[in] - The size of random vectore that is required.
513 * @rnd_ptr[out] - The output buffer of size not less, than rndSizeWords.
514 *
515 * @return CCError_t - On success CC_OK is returned, on failure a
516 * value MODULE_* as defined in ...
517 */
CC_RsaGenerateVectorInRangeX931(CCRndContext_t * rndContext_ptr,uint32_t rndSizeWords,uint32_t * rnd_ptr)518 CCError_t CC_RsaGenerateVectorInRangeX931(
519 CCRndContext_t *rndContext_ptr,
520 uint32_t rndSizeWords,
521 uint32_t *rnd_ptr)
522 {
523 /* MIN_WORD = rounded up MS word of (2^(32*rndSizeWords-1))*sqwRoot(2)*/
524 #define MIN_VAL 0xB504F334 /* RL minimal value of MS word of rnd vect. */
525
526 /* FUNCTION DECLARATIONS */
527
528 CCError_t error = CC_OK;
529 uint32_t msWord;
530 int32_t i;
531 CCBool_t isFound = CC_FALSE;
532 void *rndState_ptr;
533 CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
534
535 /* FUNCTION LOGIC */
536
537 /* check parameters */
538 if (rndContext_ptr == NULL)
539 return CC_RND_CONTEXT_PTR_INVALID_ERROR;
540
541 rndState_ptr = rndContext_ptr->rndState;
542 RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
543
544 if (RndGenerateVectFunc == NULL)
545 return CC_RND_GEN_VECTOR_FUNC_ERROR;
546
547 /* ......... Rnd generation .............. */
548 /* ----------------------------------------------------- */
549
550 while (1) {
551 /* Genrate random prime candidate, considered as 32-bit words */
552 error = RndGenerateVectFunc((void*)rndState_ptr,
553 (unsigned char *)rnd_ptr,
554 (size_t)rndSizeWords*sizeof(uint32_t));
555 if (error)
556 goto End;
557
558 /* Find and adust candidate for msWord inside the random *
559 * vector starting from msWord itself */
560
561 for (i = rndSizeWords-1; i >= 0; i--) {
562 /* Set MSBit to 1 */
563 msWord = rnd_ptr[i] | 0x80000000;
564
565 if (msWord > MIN_VAL) {
566 rnd_ptr[rndSizeWords-1] = msWord;
567 isFound = 1;
568 }
569
570 /* Generate new random words instead the checked yet *
571 * (for sequrity goals) */
572 if ((isFound == 1) && (i < (int32_t)rndSizeWords - 1)) {
573 error = RndGenerateVectFunc((void*)rndState_ptr,
574 (unsigned char *)&rnd_ptr[i],
575 (size_t)(rndSizeWords - 1 - i)*sizeof(uint32_t));
576 if (error)
577 goto End;
578 }
579
580 if (isFound == 1)
581 break;
582 }
583
584 if (isFound) {
585 rnd_ptr[0] |= 1; /* ensure odd result */
586 break;
587 }
588 }
589
590 End:
591 return error;
592
593 } /* End of CC_RsaGenerateVectorInRangeX931 */
594
595 #endif /*_INTERNAL_CC_NO_RSA_KG_SUPPORT*/
596 #endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
597