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