1 /*
2  * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /************* Include Files ****************/
8 #ifdef CC_IOT
9 #include "mbedtls/build_info.h"
10 #endif
11 
12 #if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
13 
14 #include "cc_pal_mem.h"
15 #include "cc_common.h"
16 #include "cc_common_math.h"
17 #include "cc_rsa_error.h"
18 #include "cc_rsa_local.h"
19 #include "pki.h"
20 #include "rsa.h"
21 #include "rsa_public.h"
22 #include "rsa_private.h"
23 #include "cc_fips_defs.h"
24 
25 /************************ Defines ******************************/
26 
27 /************************ Enums ******************************/
28 
29 /************************ Typedefs ***************************/
30 
31 /************************ Global Data ************************/
32 
33 /************************ Public Functions ******************************/
34 
35 /******************************************************************************************/
36 /**
37  * @brief CC_RsaPubKeyBuild populates a CCRsaPubKey_t structure with
38  *       the provided modulus and exponent.
39  *
40  *  Assumption : the modulus and the exponent are presented in big endian.
41  *
42  * @param[out] PubKey_ptr - a pointer to the public key structure. This structure will be
43  *            used as an input to the CC_RsaPrimEncrypt API.
44  *
45  * @param[in] Exponent_ptr - a pointer to the exponent stream of bytes ( Big endian ).
46  * @param[in] ExponentSize - The size of the exponent in bytes.
47  * @param[in] Modulus_ptr  - a pointer to the modulus stream of bytes ( Big endian ) the MS
48  *           bit must be set to '1'.
49  * @param[in] ModulusSize  - The size of the modulus in bytes. Sizes supported according to
50  *           used platform from 64 to 256 bytes and in some platforms up to 512 bytes.
51  *
52  * @return CCError_t - On success CC_OK is returned, on failure a
53  *                        value MODULE_* as defined in .
54  */
CC_RsaPubKeyBuild(CCRsaUserPubKey_t * UserPubKey_ptr,uint8_t * Exponent_ptr,size_t ExponentSize,uint8_t * Modulus_ptr,size_t ModulusSize)55 CEXPORT_C CCError_t CC_RsaPubKeyBuild(
56                CCRsaUserPubKey_t *UserPubKey_ptr,
57                uint8_t *Exponent_ptr,
58                size_t   ExponentSize,
59                uint8_t *Modulus_ptr,
60                size_t ModulusSize )
61 {
62     /* FUNCTION DECLARATIONS */
63 
64     /* the counter compare result */
65     CCCommonCmpCounter_t CounterCmpResult;
66 
67     /* the effective size in bits of the modulus buffer */
68     uint32_t ModulusEffectiveSizeInBits;
69 
70     /* the effective size in bits of the exponent buffer */
71     uint32_t ExponentEffectiveSizeInBits;
72 
73     /* the public key database pointer */
74     CCRsaPubKey_t *PubKey_ptr;
75 
76     /* the Error return code identifier */
77     CCError_t Error = CC_OK;
78 
79     /* Max Size of buffers in Key structure */
80     uint32_t  buffSizeBytes = CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES;
81 
82     /* FUNCTION LOGIC */
83     /* ................. checking the validity of the pointer arguments ....... */
84     /* ------------------------------------------------------------------------ */
85 
86     CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
87 
88     /* ...... checking the key database handle pointer .................... */
89     if (UserPubKey_ptr == NULL)
90         return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
91 
92     /* ...... checking the validity of the exponent pointer ............... */
93     if (Exponent_ptr == NULL)
94         return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
95 
96     /* ...... checking the validity of the modulus pointer .............. */
97     if (Modulus_ptr == NULL)
98         return CC_RSA_INVALID_MODULUS_POINTER_ERROR;
99 
100     if (ModulusSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
101         return CC_RSA_INVALID_MODULUS_SIZE;
102 
103     if (ExponentSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
104         return CC_RSA_INVALID_EXPONENT_SIZE;
105 
106     /* .................. copy the buffers to the key handle structure .... */
107     /* -------------------------------------------------------------------- */
108     /* setting the pointer to the key database */
109     PubKey_ptr = ( CCRsaPubKey_t * )UserPubKey_ptr->PublicKeyDbBuff;
110 
111     /* clear the public key db */
112     CC_PalMemSetZero( PubKey_ptr, sizeof(CCRsaPubKey_t) );
113 
114     /* loading the buffers to little endian order of words in array; each word is loaded according to CPU endianness */
115     Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PubKey_ptr->n, buffSizeBytes, Modulus_ptr, ModulusSize);
116     if (Error != CC_OK) {
117         Error = CC_RSA_INVALID_MODULUS_ERROR;
118         return Error;
119     }
120 
121     Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PubKey_ptr->e, buffSizeBytes, Exponent_ptr, ExponentSize);
122     if (Error != CC_OK) {
123         Error = CC_RSA_INVALID_EXPONENT_VAL;
124         goto End;
125     }
126 
127     /* .................. initializing local variables ................... */
128     /* ------------------------------------------------------------------- */
129 
130     /* .......... initializing the effective counters size in bits .......... */
131     ModulusEffectiveSizeInBits =  CC_CommonGetWordsCounterEffectiveSizeInBits(PubKey_ptr->n, (ModulusSize+3)/4);
132     ExponentEffectiveSizeInBits = CC_CommonGetWordsCounterEffectiveSizeInBits(PubKey_ptr->e, (ExponentSize+3)/4);
133 
134     /* .................. checking the validity of the counters ............... */
135     /* ------------------------------------------------------------------------ */
136     if ((ModulusEffectiveSizeInBits < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
137         (ModulusEffectiveSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
138         (ModulusEffectiveSizeInBits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS)) {
139 
140         Error = CC_RSA_INVALID_MODULUS_SIZE;
141         goto End;
142     }
143     /*  verifying the modulus is odd  */
144     if ((PubKey_ptr->n[0] & 1UL) == 0) {
145         Error = CC_RSA_MODULUS_EVEN_ERROR;
146         goto End;
147     }
148 
149     /*  checking the exponent size is not 0 in bytes */
150     if (ExponentEffectiveSizeInBits == 0) {
151         Error = CC_RSA_INVALID_EXPONENT_SIZE;
152         goto End;
153     }
154 
155     /*  verifying the exponent is less then the modulus */
156     CounterCmpResult = CC_CommonCmpMsbUnsignedCounters(Exponent_ptr, ExponentSize, Modulus_ptr, ModulusSize);
157 
158     if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
159         Error = CC_RSA_INVALID_EXPONENT_VAL;
160         goto End;
161     }
162 
163     /*  verifying the exponent is not less then 3 */
164     if (ExponentEffectiveSizeInBits < 32 && PubKey_ptr->e[0] < CC_RSA_MIN_PUB_EXP_VALUE) {
165         Error = CC_RSA_INVALID_EXPONENT_VAL;
166         goto End;
167     }
168 
169     /* ................. building the structure ............................. */
170     /* ---------------------------------------------------------------------- */
171 
172     /* setting the modulus and exponent size in bits */
173     PubKey_ptr->nSizeInBits = ModulusEffectiveSizeInBits;
174     PubKey_ptr->eSizeInBits = ExponentEffectiveSizeInBits;
175 
176     /* ................ initialize the low level data .............. */
177     Error = RsaInitPubKeyDb(PubKey_ptr);
178 
179     if (Error != CC_OK) {
180         Error = CC_RSA_KEY_GENERATION_FAILURE_ERROR;
181         goto End;
182     }
183 
184     /* ................ set the tag ................ */
185     UserPubKey_ptr->valid_tag = CC_RSA_PUB_KEY_VALIDATION_TAG;
186 
187     /* ................. end of the function .................................. */
188     /* ------------------------------------------------------------------------ */
189 
190     End:
191 
192     /* if the structure created is not valid - clear it */
193     if (Error != CC_OK) {
194         CC_PalMemSetZero(UserPubKey_ptr, sizeof(CCRsaUserPubKey_t));
195         return Error;
196     }
197 
198     return CC_OK;
199 
200 }/* END OF CC_RsaPubKeyBuild */
201 
202 
203 /******************************************************************************************/
204 /**
205  * @brief CC_RsaPrivKeyBuild populates a CCRsaPrivKey_t structure with
206  *        the provided modulus and exponent, marking the key as a "non-CRT" key.
207  *
208  *        Assumption : the modulus and the exponent are presented in big endian.
209  *
210  * @param[out] UserPrivKey_ptr - a pointer to the public key structure. this structure will be used as
211  *                          an input to the CC_RsaPrimDecrypt API.
212  * @param[in] PrivExponent_ptr - a pointer to the private exponent stream of bytes ( Big endian ).
213  * @param[in] PrivExponentSize - the size of the private exponent in bytes.
214  * @param[in] Exponent_ptr - a pointer to the exponent stream of bytes ( Big endian ).
215  * @param[in] ExponentSize - the size of the exponent in bytes.
216  * @param[in] Modulus_ptr  - a pointer to the modulus stream of bytes ( Big endian ) the MS
217  *            bit must be set to '1'.
218  * @param[in] ModulusSize  - the size of the modulus in bytes. Sizes supported according to
219  *            used platform from 64 to 256 bytes and in some platforms up to 512 bytes.
220  *
221  * @return CCError_t - On success CC_OK is returned, on failure a
222  *                       value MODULE_* as defined in ...
223  *
224  */
CC_RsaPrivKeyBuild(CCRsaUserPrivKey_t * UserPrivKey_ptr,uint8_t * PrivExponent_ptr,size_t PrivExponentSize,uint8_t * PubExponent_ptr,size_t PubExponentSize,uint8_t * Modulus_ptr,size_t ModulusSize)225 CEXPORT_C CCError_t CC_RsaPrivKeyBuild(CCRsaUserPrivKey_t       *UserPrivKey_ptr,
226                          uint8_t             *PrivExponent_ptr,
227                          size_t               PrivExponentSize,
228                          uint8_t             *PubExponent_ptr,
229                          size_t               PubExponentSize,
230                          uint8_t             *Modulus_ptr,
231                          size_t               ModulusSize )
232 {
233     /* FUNCTION DECLARATIONS */
234 
235     /* the counter compare result */
236     CCCommonCmpCounter_t CounterCmpResult;
237 
238     /* the effective size in bits of the modulus buffer */
239     uint32_t ModulusEffectiveSizeInBits;
240 
241     /* the effective sizes in bits of the private and public exponents */
242     uint32_t PrivExponentEffectiveSizeInBits, PubExponentEffectiveSizeInBits;
243 
244     /* the private key database pointer */
245     CCRsaPrivKey_t *PrivKey_ptr;
246 
247     /* Max Size of buffers in Key structure */
248     uint32_t  buffSizeBytes = CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES;
249 
250     /* the Error return code identifier */
251     CCError_t Error = CC_OK;
252 
253     /* FUNCTION LOGIC */
254 
255     /* ................. checking the validity of the pointer arguments ....... */
256     /* ------------------------------------------------------------------------ */
257     CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
258 
259     /* ...... checking the key database handle pointer .................... */
260     if (UserPrivKey_ptr == NULL)
261         return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
262 
263     /* ...... checking the validity of the exponents pointers ........... */
264     if (PrivExponent_ptr == NULL)
265         return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
266 
267     /* ...... checking the validity of the modulus pointer .............. */
268     if (Modulus_ptr == NULL)
269         return CC_RSA_INVALID_MODULUS_POINTER_ERROR;
270 
271     /* ...... checking the validity of the modulus size, private exponent can not be more than 256 bytes .............. */
272     if (ModulusSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
273         return CC_RSA_INVALID_MODULUS_SIZE;
274 
275     if (PrivExponentSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
276         return CC_RSA_INVALID_EXPONENT_SIZE;
277 
278     if (PubExponent_ptr != NULL &&
279         PubExponentSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES)
280         return CC_RSA_INVALID_EXPONENT_SIZE;
281 
282 
283     /* .................. copy the buffers to the key handle structure .... */
284     /* -------------------------------------------------------------------- */
285 
286     /* setting the pointer to the key database */
287     PrivKey_ptr = (CCRsaPrivKey_t *)UserPrivKey_ptr->PrivateKeyDbBuff;
288 
289     /* clear the private key db */
290     CC_PalMemSetZero(PrivKey_ptr, sizeof(CCRsaPrivKey_t));
291 
292     /* loading the buffers to little endian order of words in array; each word is loaded according to CPU endianness */
293     Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->n, buffSizeBytes, Modulus_ptr, ModulusSize);
294     if (Error != CC_OK) {
295         Error = CC_RSA_INVALID_MODULUS_ERROR;
296         return Error;
297     }
298 
299     Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.NonCrt.d, buffSizeBytes,
300                                 PrivExponent_ptr, PrivExponentSize);
301     if (Error != CC_OK) {
302         Error = CC_RSA_INVALID_EXPONENT_VAL;
303         goto End;
304     }
305 
306     /* get actual sizes of modulus and private exponent */
307     ModulusEffectiveSizeInBits =
308     CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->n, (ModulusSize+3)/4);
309 
310     PrivExponentEffectiveSizeInBits =
311     CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.NonCrt.d, (PrivExponentSize+3)/4);
312 
313 
314     /* .................. checking the validity of the counters ............... */
315     /* ------------------------------------------------------------------------ */
316 
317     /*  checking the size of the modulus  */
318     if (( ModulusEffectiveSizeInBits < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
319         ( ModulusEffectiveSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS ) ||
320         ( ModulusEffectiveSizeInBits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS)) {
321         Error = CC_RSA_INVALID_MODULUS_SIZE;
322         goto End;
323     }
324 
325     /*  verifying the modulus is odd  */
326     if ((PrivKey_ptr->n[0] & 1UL) == 0) {
327         Error = CC_RSA_MODULUS_EVEN_ERROR;
328         goto End;
329     }
330 
331     /*  checking the priv. exponent size is not 0 in bytes */
332     if (PrivExponentEffectiveSizeInBits == 0) {
333         Error = CC_RSA_INVALID_EXPONENT_SIZE;
334         goto End;
335     }
336 
337     /* verifying the priv. exponent is less then the modulus */
338     CounterCmpResult = CC_CommonCmpMsbUnsignedCounters(PrivExponent_ptr, PrivExponentSize,
339                                   Modulus_ptr, ModulusSize);
340 
341     if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
342         Error = CC_RSA_INVALID_EXPONENT_VAL;
343         goto End;
344     }
345 
346     /* verifying the priv. exponent is not less then 1 */
347     if (PrivExponentEffectiveSizeInBits < 32 &&
348         PrivKey_ptr->PriveKeyDb.NonCrt.d[0] < CC_RSA_MIN_PRIV_EXP_VALUE) {
349         Error = CC_RSA_INVALID_EXPONENT_VAL;
350         goto End;
351     }
352 
353     /*  checking that the public exponent is an integer between 3 and modulus - 1 */
354     if (PubExponent_ptr != NULL) {
355         /* loading the buffer to little endian order of words in array; each word is loaded according to CPU endianness */
356         Error = CC_CommonConvertMsbLsbBytesToLswMswWords( PrivKey_ptr->PriveKeyDb.NonCrt.e, buffSizeBytes,
357                                      PubExponent_ptr, PubExponentSize);
358         if (Error) {
359             Error = CC_RSA_INVALID_EXPONENT_VAL;
360             goto End;
361         }
362 
363         PubExponentEffectiveSizeInBits =
364         CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.NonCrt.e, (PubExponentSize+3)/4);
365 
366         /* verifying that the exponent is not less than 3 */
367         if (PubExponentEffectiveSizeInBits < 32 &&
368             PrivKey_ptr->PriveKeyDb.NonCrt.e[0] < CC_RSA_MIN_PUB_EXP_VALUE) {
369             Error = CC_RSA_INVALID_EXPONENT_VAL;
370             goto End;
371         }
372 
373         /* verifying that the public exponent is less than the modulus */
374         CounterCmpResult = CC_CommonCmpMsbUnsignedCounters(PubExponent_ptr, PubExponentSize,
375                                       Modulus_ptr, ModulusSize);
376 
377         if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
378             Error = CC_RSA_INVALID_EXPONENT_VAL;
379             goto End;
380         }
381     } else {
382         PubExponentEffectiveSizeInBits = 0;
383     }
384 
385 
386     /* ................. building the structure ............................. */
387     /* ---------------------------------------------------------------------- */
388 
389     /* set the mode to non CRT mode */
390     PrivKey_ptr->OperationMode = CC_RSA_NoCrt;
391 
392     /* set the key source as external */
393     PrivKey_ptr->KeySource = CC_RSA_ExternalKey;
394 
395     /* setting the modulus and exponent size in bits */
396     PrivKey_ptr->nSizeInBits                   = ModulusEffectiveSizeInBits;
397     PrivKey_ptr->PriveKeyDb.NonCrt.dSizeInBits = PrivExponentEffectiveSizeInBits;
398     PrivKey_ptr->PriveKeyDb.NonCrt.eSizeInBits = PubExponentEffectiveSizeInBits;
399 
400     /* ................ initialize the low level data .............. */
401     Error = RsaInitPrivKeyDb(PrivKey_ptr);
402 
403     if (Error) {
404         Error = CC_RSA_INTERNAL_ERROR;
405         goto End;
406     }
407 
408     /* ................ set the tag ................ */
409     UserPrivKey_ptr->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
410 
411     /* ................. end of the function .................................. */
412     /* ------------------------------------------------------------------------ */
413 
414     End:
415 
416     /* if the structure created is not valid - clear it */
417     if (Error != CC_OK) {
418         CC_PalMemSetZero(UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
419     }
420 
421     return Error;
422 
423 }/* END OF CC_RsaPrivKeyBuild */
424 
425 /******************************************************************************************
426 
427    @brief CC_RsaPrivKeyCrtBuild populates a CCRsaPrivKey_t structure with
428       the provided parameters, marking the key as a "CRT" key.
429 
430     Note: The "First" factor P must be great, than the "Second" factor Q.
431 
432 
433    @param[out] UserPrivKey_ptr - A pointer to the public key structure.
434                 This structure is used as input to the CC_RsaPrimDecrypt API.
435    @param[in] P_ptr - A pointer to the first factor stream of bytes (Big-Endian format)
436    @param[in] PSize - The size of the first factor, in bytes.
437    @param[in] Q_ptr - A pointer to the second factor stream of bytes (Big-Endian format)
438    @param[in] QSize - The size of the second factor, in bytes.
439    @param[in] dP_ptr - A pointer to the first factor's CRT exponent stream of bytes (Big-Endian format)
440    @param[in] dPSize - The size of the first factor's CRT exponent, in bytes.
441    @param[in] dQ_ptr - A pointer to the second factor's CRT exponent stream of bytes (Big-Endian format)
442    @param[in] dQSize - The size of the second factor's CRT exponent, in bytes.
443    @param[in] qInv_ptr - A pointer to the first CRT coefficient stream of bytes (Big-Endian format)
444    @param[in] qInvSize - The size of the first CRT coefficient, in bytes.
445 
446 */
CC_RsaPrivKeyCrtBuild(CCRsaUserPrivKey_t * UserPrivKey_ptr,uint8_t * P_ptr,size_t PSize,uint8_t * Q_ptr,size_t QSize,uint8_t * dP_ptr,size_t dPSize,uint8_t * dQ_ptr,size_t dQSize,uint8_t * qInv_ptr,size_t qInvSize)447 CEXPORT_C CCError_t CC_RsaPrivKeyCrtBuild(
448                            CCRsaUserPrivKey_t *UserPrivKey_ptr,
449                            uint8_t *P_ptr,
450                            size_t   PSize,
451                            uint8_t *Q_ptr,
452                            size_t   QSize,
453                            uint8_t *dP_ptr,
454                            size_t   dPSize,
455                            uint8_t *dQ_ptr,
456                            size_t   dQSize,
457                            uint8_t *qInv_ptr,
458                            size_t   qInvSize)
459 {
460     /* FUNCTION DECLARATIONS */
461 
462     /* the counter compare result */
463     CCCommonCmpCounter_t CounterCmpResult;
464 
465     /* the effective size in bits of the modulus factors buffer */
466     uint32_t P_EffectiveSizeInBits;
467     uint32_t Q_EffectiveSizeInBits;
468     uint32_t dP_EffectiveSizeInBits;
469     uint32_t dQ_EffectiveSizeInBits;
470     uint32_t qInv_EffectiveSizeInBits;
471     uint32_t ModulusEffectiveSizeInBits;
472 
473     /* the private key database pointer */
474     CCRsaPrivKey_t *PrivKey_ptr;
475 
476     /* Max Size of buffers in CRT Key structure */
477     uint32_t  buffSizeBytes;
478 
479     /* the Error return code identifier */
480     CCError_t Error = CC_OK;
481 
482     /* FUNCTION LOGIC */
483 
484 
485     /* ................. checking the validity of the pointer arguments ....... */
486     /* ------------------------------------------------------------------------ */
487     CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
488 
489     /* ...... checking the key database handle pointer .................... */
490     if (UserPrivKey_ptr == NULL)
491         return CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
492 
493     /* checking the first factor pointer validity */
494     if (P_ptr == NULL)
495         return CC_RSA_INVALID_CRT_FIRST_FACTOR_POINTER_ERROR;
496 
497     /* checking the second factor pointer validity */
498     if (Q_ptr == NULL)
499         return CC_RSA_INVALID_CRT_SECOND_FACTOR_POINTER_ERROR;
500 
501     /* checking the first factor exponent pointer validity */
502     if (dP_ptr == NULL)
503         return CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_PTR_ERROR;
504 
505     /* checking the second factor exponent pointer validity */
506     if (dQ_ptr == NULL)
507         return CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_PTR_ERROR;
508 
509     /* checking the CRT coefficient */
510     if (qInv_ptr == NULL)
511         return CC_RSA_INVALID_CRT_COEFFICIENT_PTR_ERROR;
512 
513     /* checking the input sizes */
514     if (PSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES/2 ||
515         QSize > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BYTES/2) {
516         return CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR;
517     }
518 
519     if (dPSize > PSize ||
520         dQSize > QSize ||
521         qInvSize > PSize) {
522         return CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR;
523     }
524 
525     buffSizeBytes = 4*((PSize + 3)/4) + 4;
526     /* verifying the first factor exponent is less then the first factor */
527     CounterCmpResult =
528     CC_CommonCmpMsbUnsignedCounters(dP_ptr, dPSize, P_ptr, PSize);
529 
530     if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
531         return CC_RSA_INVALID_CRT_FIRST_FACTOR_EXPONENT_VAL;
532     }
533 
534     /* verifying the second factor exponent is less then the second factor */
535     CounterCmpResult =
536     CC_CommonCmpMsbUnsignedCounters(dQ_ptr, dQSize, Q_ptr, QSize);
537 
538     if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
539         return CC_RSA_INVALID_CRT_SECOND_FACTOR_EXPONENT_VAL;
540     }
541 
542     /* verifying the CRT coefficient is less then the first factor */
543     CounterCmpResult =
544     CC_CommonCmpMsbUnsignedCounters(qInv_ptr, qInvSize, P_ptr, PSize);
545 
546     if (CounterCmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
547         return CC_RSA_INVALID_CRT_COEFF_VAL;
548     }
549 
550 
551     /* .................. copy the buffers to the key handle structure .... */
552     /* -------------------------------------------------------------------- */
553 
554     /* setting the pointer to the key database */
555     PrivKey_ptr = (CCRsaPrivKey_t*)UserPrivKey_ptr->PrivateKeyDbBuff;
556 
557     /* clear the private key db */
558     CC_PalMemSetZero(PrivKey_ptr, sizeof(CCRsaPrivKey_t));
559 
560     /* load the buffers to the data base */
561     Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.P, buffSizeBytes, P_ptr, PSize);
562     if (Error != CC_OK) {
563         Error = CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE_ERROR;
564         goto End;
565     }
566 
567     Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.Q, buffSizeBytes, Q_ptr, QSize);
568     if (Error != CC_OK) {
569         Error = CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE_ERROR;
570         goto End;
571     }
572 
573     Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.dP, buffSizeBytes, dP_ptr, dPSize);
574     if (Error != CC_OK) {
575         Error = CC_RSA_INVALID_CRT_FIRST_FACTOR_EXP_SIZE_ERROR;
576         goto End;
577     }
578 
579     Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.dQ, buffSizeBytes, dQ_ptr, dQSize);
580     if (Error != CC_OK) {
581         Error = CC_RSA_INVALID_CRT_SECOND_FACTOR_EXP_SIZE_ERROR;
582         goto End;
583     }
584 
585     Error = CC_CommonConvertMsbLsbBytesToLswMswWords(PrivKey_ptr->PriveKeyDb.Crt.qInv, buffSizeBytes, qInv_ptr, qInvSize);
586     if (Error != CC_OK) {
587         Error = CC_RSA_INVALID_CRT_COEFFICIENT_SIZE_ERROR;
588         goto End;
589     }
590 
591     /* ............... initialize local variables ......................... */
592     /* -------------------------------------------------------------------- */
593 
594     /* initializing the effective counters size in bits */
595     P_EffectiveSizeInBits =
596     CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.P, (PSize+3)/4);
597 
598     Q_EffectiveSizeInBits =
599     CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.Q, (QSize+3)/4);
600 
601     dP_EffectiveSizeInBits =
602     CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.dP, (dPSize+3)/4);
603 
604     dQ_EffectiveSizeInBits =
605     CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.dQ, (dQSize+3)/4);
606 
607     qInv_EffectiveSizeInBits =
608     CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->PriveKeyDb.Crt.qInv, (qInvSize+3)/4);
609 
610     /*  the first factor size is not 0 in bits */
611     if (P_EffectiveSizeInBits == 0|| P_EffectiveSizeInBits > 8*PSize) {
612         Error = CC_RSA_INVALID_CRT_FIRST_FACTOR_SIZE;
613         goto End;
614     }
615 
616     /* the second factor size is not 0 in bits */
617     if (Q_EffectiveSizeInBits == 0 || Q_EffectiveSizeInBits > 8*QSize) {
618         Error = CC_RSA_INVALID_CRT_SECOND_FACTOR_SIZE;
619         goto End;
620     }
621 
622     /* checking that sizes of dP, dQ, qInv > 0 */
623     if (dP_EffectiveSizeInBits == 0 || dQ_EffectiveSizeInBits == 0 || qInv_EffectiveSizeInBits == 0) {
624         Error = CC_RSA_INVALID_CRT_PARAMETR_SIZE_ERROR;
625         goto End;
626     }
627 
628 
629 
630     /* ............... calculate the modulus N ........................... */
631     /* -------------------------------------------------------------------- */
632 
633 
634     Error = PkiLongNumMul(PrivKey_ptr->PriveKeyDb.Crt.P, P_EffectiveSizeInBits,
635                      PrivKey_ptr->PriveKeyDb.Crt.Q, PrivKey_ptr->n);
636     if (Error != CC_OK) {
637         Error = CC_RSA_INTERNAL_ERROR;
638         goto End;
639     }
640 
641     ModulusEffectiveSizeInBits =
642     CC_CommonGetWordsCounterEffectiveSizeInBits(PrivKey_ptr->n, (2*CALC_FULL_32BIT_WORDS(P_EffectiveSizeInBits)));
643 
644     /* .................. checking the validity of the counters ............... */
645     /* ------------------------------------------------------------------------ */
646 
647     /* the size of the modulus  */
648     if (( ModulusEffectiveSizeInBits < CC_RSA_MIN_VALID_KEY_SIZE_VALUE_IN_BITS) ||
649         ( ModulusEffectiveSizeInBits > CC_RSA_MAX_VALID_KEY_SIZE_VALUE_IN_BITS) ||
650         ( ModulusEffectiveSizeInBits % CC_RSA_VALID_KEY_SIZE_MULTIPLE_VALUE_IN_BITS)) {
651         Error = CC_RSA_INVALID_MODULUS_SIZE;
652         goto End;
653     }
654 
655     if ((P_EffectiveSizeInBits + Q_EffectiveSizeInBits != ModulusEffectiveSizeInBits) &&
656         (P_EffectiveSizeInBits + Q_EffectiveSizeInBits != ModulusEffectiveSizeInBits - 1)) {
657         Error = CC_RSA_INVALID_CRT_FIRST_AND_SECOND_FACTOR_SIZE;
658         goto End;
659     }
660 
661 
662     /* ................. building the structure ............................. */
663     /* ---------------------------------------------------------------------- */
664 
665     /* set the mode to CRT mode */
666     PrivKey_ptr->OperationMode = CC_RSA_Crt;
667 
668     /* set the key source as external */
669     PrivKey_ptr->KeySource = CC_RSA_ExternalKey;
670 
671     /* loading to structure the buffer sizes... */
672 
673     PrivKey_ptr->PriveKeyDb.Crt.PSizeInBits    = P_EffectiveSizeInBits;
674     PrivKey_ptr->PriveKeyDb.Crt.QSizeInBits    = Q_EffectiveSizeInBits;
675     PrivKey_ptr->PriveKeyDb.Crt.dPSizeInBits   = dP_EffectiveSizeInBits;
676     PrivKey_ptr->PriveKeyDb.Crt.dQSizeInBits   = dQ_EffectiveSizeInBits;
677     PrivKey_ptr->PriveKeyDb.Crt.qInvSizeInBits = qInv_EffectiveSizeInBits;
678     PrivKey_ptr->nSizeInBits = ModulusEffectiveSizeInBits;
679 
680     /* ................ initialize the low level data .............. */
681     Error = RsaInitPrivKeyDb(PrivKey_ptr);
682 
683     if (Error != CC_OK) {
684         Error = CC_RSA_INTERNAL_ERROR;
685         goto End;
686     }
687 
688     /* ................ set the tag ................ */
689     UserPrivKey_ptr->valid_tag = CC_RSA_PRIV_KEY_VALIDATION_TAG;
690 
691     /* ................. end of the function .................................. */
692     /* ------------------------------------------------------------------------ */
693 
694     End:
695 
696     /* if the structure created is not valid - clear it */
697     if (Error != CC_OK) {
698         CC_PalMemSetZero(UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
699         return Error;
700     }
701 
702     return Error;
703 
704 }/* END OF CC_RsaPrivKeyCrtBuild */
705 
706 
707 /******************************************************************************************
708    @brief CC_RsaPubKeyGet gets the e,n public key from the database.
709 
710    @param[in] UserPubKey_ptr - A pointer to the public key structure.
711                    This structure is used as input to the CC_RsaPrimEncrypt API.
712 
713    @param[out] Exponent_ptr - A pointer to the exponent stream of bytes (Big-Endian format)
714    @param[in,out] ExponentSize_ptr - the size of the exponent buffer in bytes, it is updated to the
715           actual size of the exponent, in bytes.
716    @param[out] Modulus_ptr  - A pointer to the modulus stream of bytes (Big-Endian format).
717                The MS (most significant) bit must be set to '1'.
718    @param[in,out] ModulusSize_ptr  - the size of the modulus buffer in bytes, it is updated to the
719           actual size of the modulus, in bytes.
720 
721    NOTE: All members of input UserPrivKey structure must be initialized, including public key
722      e pointer and it size.
723 
724 */
CC_RsaPubKeyGet(CCRsaUserPubKey_t * UserPubKey_ptr,uint8_t * Exponent_ptr,size_t * ExponentSize_ptr,uint8_t * Modulus_ptr,size_t * ModulusSize_ptr)725 CEXPORT_C CCError_t CC_RsaPubKeyGet(
726                      CCRsaUserPubKey_t *UserPubKey_ptr,
727                      uint8_t  *Exponent_ptr,
728                      size_t   *ExponentSize_ptr,
729                      uint8_t  *Modulus_ptr,
730                      size_t   *ModulusSize_ptr )
731 {
732     /* LOCAL DECLERATIONS */
733 
734     /* the size in bytes of the modulus and the exponent */
735     uint32_t nSizeInBytes;
736     uint32_t eSizeInBytes;
737     /* the public key database pointer */
738     CCRsaPubKey_t *PubKey_ptr;
739 
740     CCError_t Error;
741 
742     /* FUNCTION DECLERATIONS */
743 
744 
745     /* ................. checking the validity of the pointer arguments ....... */
746     /* ------------------------------------------------------------------------ */
747     CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
748 
749     /* ...... checking the key database handle pointer .................... */
750     if (UserPubKey_ptr == NULL)
751         return CC_RSA_INVALID_PUB_KEY_STRUCT_POINTER_ERROR;
752 
753     /* ...... checking the validity of the exponent pointer ............... */
754     if (Exponent_ptr == NULL && Modulus_ptr != NULL)
755         return CC_RSA_INVALID_EXPONENT_POINTER_ERROR;
756 
757     /* ...... checking the validity of the modulus pointer .............. */
758     if (Modulus_ptr == NULL && Exponent_ptr != NULL)
759         return CC_RSA_INVALID_MODULUS_POINTER_ERROR;
760 
761     if (ExponentSize_ptr == NULL)
762         return CC_RSA_INVALID_EXP_BUFFER_SIZE_POINTER;
763 
764     if (ModulusSize_ptr == NULL)
765         return CC_RSA_INVALID_MOD_BUFFER_SIZE_POINTER;
766 
767     /* if the users TAG is illegal return an error - the context is invalid */
768     if (UserPubKey_ptr->valid_tag != CC_RSA_PUB_KEY_VALIDATION_TAG)
769         return CC_RSA_PUB_KEY_VALIDATION_TAG_ERROR;
770 
771     /* ...... checking the exponent size ................................ */
772 
773     /* setting the pointer to the key database */
774     PubKey_ptr = ( CCRsaPubKey_t * )UserPubKey_ptr->PublicKeyDbBuff;
775 
776     /* calculating the required size in bytes */
777     nSizeInBytes = CALC_FULL_BYTES(PubKey_ptr->nSizeInBits);
778     eSizeInBytes = CALC_FULL_BYTES(PubKey_ptr->eSizeInBits);
779 
780     /* return the modulus size and exit */
781     if (Exponent_ptr == NULL && Modulus_ptr == NULL){
782         *ModulusSize_ptr  = nSizeInBytes;
783         *ExponentSize_ptr = eSizeInBytes;
784         return CC_OK;
785     }
786     /* if the size of the modulus is to small return error */
787     if (nSizeInBytes > *ModulusSize_ptr)
788         return CC_RSA_INVALID_MODULUS_SIZE;
789 
790     /* if the size of the exponent buffer is to small return error */
791     if (eSizeInBytes > *ExponentSize_ptr)
792         return CC_RSA_INVALID_EXPONENT_SIZE;
793 
794     /* .............. loading the output arguments and buffers ............... */
795     /* ----------------------------------------------------------------------- */
796 
797     /* loading the buffers */
798 
799     Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(Exponent_ptr, 4*((*ExponentSize_ptr+3)/4),
800                                 PubKey_ptr->e, eSizeInBytes );
801     if (Error != CC_OK) {
802         Error = CC_RSA_INVALID_EXPONENT_SIZE;
803         goto End;
804     }
805 
806     Error = CC_CommonConvertLswMswWordsToMsbLsbBytes(Modulus_ptr, 4*((*ModulusSize_ptr+3)/4),
807                                 PubKey_ptr->n, nSizeInBytes );
808     if (Error != CC_OK) {
809         Error = CC_RSA_INVALID_MODULUS_SIZE;
810         goto End;
811     }
812 
813     /* updating the buffer sizes */
814     *ModulusSize_ptr  = (uint16_t)nSizeInBytes;
815     *ExponentSize_ptr = (uint16_t)eSizeInBytes;
816 
817 End:
818     if (Error != CC_OK) {
819         CC_PalMemSetZero(Modulus_ptr, nSizeInBytes);
820         CC_PalMemSetZero(Exponent_ptr, eSizeInBytes);
821         return Error;
822     }
823 
824     return CC_OK;
825 
826 }/* END OF CC_RsaPubKeyGet */
827 
828 #endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
829