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