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 <stdbool.h>
16 #include "cc_rsa_prim.h"
17 #include "cc_rsa_error.h"
18 #include "cc_rsa_types.h"
19 #include "cc_rsa_local.h"
20 #include "cc_fips_defs.h"
21 
22 /************************ Defines ******************************/
23 
24 /* canceling the lint warning:
25    Use of goto is deprecated */
26 /*lint --e{801} */
27 #if ( CC_HASH_USER_CTX_SIZE_IN_WORDS > CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS )
28 #error CC_PKA_RSA_HASH_CTX_SIZE_IN_WORDS OR CC_HASH_USER_CTX_SIZE_IN_WORDS do not defined correctly.
29 #endif
30 
31 /************************ Enums ******************************/
32 /************************ Typedefs ***************************/
33 /************************ Global Data ************************/
34 /************* Private function prototype ********************/
35 
36 
37 /***************** Public Functions **************************/
38 
39 #ifndef _INTERNAL_CC_NO_RSA_SIGN_SUPPORT
40 /**********************************************************************************************************/
41 /**
42    \brief RSA_SignInit initializes the Signing
43    multi-call algorithm as defined in PKCS#1 v1.5 and 2.1
44 
45     NOTE: 1. In PSS_Sign v2.1 MD5 is not supported, since it is not recommended
46          by the PKCS#1 v2.1.
47           2. According to thesaid standard, implementation of the function
48          for version v1.5 is based on DER encoding of the algorithm info.
49 
50            This function does not do cryptographic processing. Rather, it
51            prepares a context that is used by the Update and Finish functions.
52 
53    @param[in,out] UserContext_ptr - A pointer to a Context. The value returned here
54                                 must be passed to the Update and Finish functions.
55    @param[in] UserPrivKey_ptr - A pointer to the private key data structure.
56                   \note The representation (pair or quintuple) and hence the
57                   algorithm (CRT or not) is determined by the Private Key data structure.
58                   Using of the CC_BuildPrivKey or CC_BuildPrivKeyCRT determines
59                   which algorithm will be used.
60    @param[in] rsaHashMode - The enumerator value, defining the hash function to be used:
61              SHA-1SHA224/256/384/512, MD5 (MD5 allowed only in v1.5).
62              The hash functions recommended by PKCS#1 v2.1 are:
63                          256/384/512. Also allowed "After" HASH modes for said functions.
64    @param[in] MGF - The mask generation function. PKCS#1 v2.1
65                     defines MGF1, so the only value allowed here is CC_PKCS1_MGF1.
66    @param[in] SaltLen - The Length of the Salt buffer (relevant for PKCS#1 Ver 2.1 only,
67                         typically lengths is 0 or hLen). FIPS 186-4 requires, that SaltLen <= hlen.
68                         If SaltLen > KeySize - hLen - 2, the function returns an error.
69    @param[in] PKCS1_ver - Ver 1.5 or 2.1, according to the functionality required.
70 
71    @return CCError_t - CC_OK, or error
72 */
CC_RsaSignInit(CCRsaPrivUserContext_t * UserContext_ptr,CCRsaUserPrivKey_t * UserPrivKey_ptr,CCRsaHashOpMode_t rsaHashMode,CCPkcs1Mgf_t MGF,size_t SaltLen,CCPkcs1Version_t PKCS1_ver)73 CEXPORT_C CCError_t CC_RsaSignInit(CCRsaPrivUserContext_t *UserContext_ptr,
74                        CCRsaUserPrivKey_t *UserPrivKey_ptr,
75                        CCRsaHashOpMode_t rsaHashMode,
76                        CCPkcs1Mgf_t MGF,
77                        size_t  SaltLen,
78                        CCPkcs1Version_t PKCS1_ver)
79 {
80     /* FUNCTION DECLERATIONS */
81 
82     /* The return error identifier */
83     CCError_t Error = CC_OK;
84 
85     /* defining a pointer to the active context allcated by the CCM */
86     RSAPrivContext_t *ccmWorkingContext_ptr;
87     /*Pointer to the private key*/
88     CCRsaPrivKey_t *PrivKey_ptr ;
89     /*The modulus size in Octets*/
90     uint16_t ModulusSizeBytes = 0;
91 #ifdef USE_MBEDTLS_CRYPTOCELL
92     const mbedtls_md_info_t *md_info=NULL;
93 #endif
94 
95     /* FUNCTION LOGIC */
96 
97     /* .... aquiring the RSA context ...... */
98     ccmWorkingContext_ptr = (RSAPrivContext_t*)((void*)UserContext_ptr->context_buff);
99 
100     /* ............... checking the parameters validity ................... */
101     /* -------------------------------------------------------------------- */
102 
103     /* if the users context ID pointer is NULL return an error */
104     if (UserContext_ptr == NULL){
105             return CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;
106     }
107 
108     /*if the private key object is NULL return an error*/
109     if (UserPrivKey_ptr == NULL){
110             Error = CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR;
111             goto End;
112     }
113 
114     /* check if the hash operation mode is legal */
115     if (rsaHashMode >= CC_RSA_HASH_NumOfModes){
116             Error = CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
117             goto End;
118     }
119 
120     /* check if the MGF operation mode is legal */
121     if (MGF >= CC_RSA_NumOfMGFFunctions){
122             Error = CC_RSA_MGF_ILLEGAL_ARG_ERROR;
123             goto End;
124     }
125 
126     /* check that the PKCS1 version argument is legal*/
127     if (PKCS1_ver >= CC_RSA_NumOf_PKCS1_versions){
128             Error = CC_RSA_PKCS1_VER_ARG_ERROR;
129             goto End;
130     }
131 
132     if (UserPrivKey_ptr->valid_tag != CC_RSA_PRIV_KEY_VALIDATION_TAG){
133             Error = CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR;
134             goto End;
135     }
136 
137     /*According to the PKCS1 ver 2.1 standard it is not recommended to use
138          MD5 hash therefore we do not support it */
139     if (PKCS1_ver == CC_PKCS1_VER21 && rsaHashMode == CC_RSA_HASH_MD5_mode){
140             Error = CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
141             goto End;
142     }
143 
144     if (PKCS1_ver == CC_PKCS1_VER21) {
145         /*Initializing the Modulus Size in Bytes needed for SaltLength parameter check*/
146         PrivKey_ptr = (CCRsaPrivKey_t *)UserPrivKey_ptr->PrivateKeyDbBuff;
147 
148         /*Note: the (-1) is due to the PKCS#1 Ver2.1 standard section 9.1.1*/
149         ModulusSizeBytes =  (uint16_t)((PrivKey_ptr->nSizeInBits -1) / 8);
150         if ((PrivKey_ptr->nSizeInBits -1) % 8)
151             ModulusSizeBytes++;
152     }
153 
154     /*Reset the Context handler for improper previous values initialized*/
155     CC_PalMemSetZero(UserContext_ptr, sizeof(CCRsaPrivUserContext_t));
156 
157     /* ................. loading the context .................................. */
158     /* ------------------------------------------------------------------------ */
159 
160     /*Initializing the Hash operation mode in the RSA Context level*/
161     ccmWorkingContext_ptr->RsaHashOperationMode = rsaHashMode;
162 
163     if (RsaSupportedHashModes_t[rsaHashMode] == CC_FALSE){
164         Error = CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
165         goto End;
166     }
167 
168     ccmWorkingContext_ptr->HashOperationMode = RsaHashInfo_t[rsaHashMode].hashMode;
169     ccmWorkingContext_ptr->HASH_Result_Size = RsaHashInfo_t[rsaHashMode].hashResultSize;
170 
171     if ( (ccmWorkingContext_ptr->HashOperationMode == CC_HASH_SHA384_mode) ||
172          (ccmWorkingContext_ptr->HashOperationMode == CC_HASH_SHA512_mode) )
173         ccmWorkingContext_ptr->HashBlockSize = CC_HASH_SHA512_BLOCK_SIZE_IN_WORDS;
174     else
175         ccmWorkingContext_ptr->HashBlockSize = CC_HASH_BLOCK_SIZE_IN_WORDS;
176 
177 
178     if ( (rsaHashMode == CC_RSA_HASH_MD5_mode ) ||
179          (rsaHashMode == CC_RSA_HASH_SHA1_mode ) ||
180          (rsaHashMode == CC_RSA_HASH_SHA224_mode ) ||
181          (rsaHashMode == CC_RSA_HASH_SHA256_mode ) ||
182          (rsaHashMode == CC_RSA_HASH_SHA384_mode ) ||
183          (rsaHashMode == CC_RSA_HASH_SHA512_mode ) )
184         ccmWorkingContext_ptr->doHash = true; /* for actual Hash modes */
185     else
186         ccmWorkingContext_ptr->doHash = false;
187 
188 
189     /* Init HASH */
190     if (ccmWorkingContext_ptr->doHash) {
191 #ifdef USE_MBEDTLS_CRYPTOCELL
192         md_info = mbedtls_md_info_from_type(RsaHash_CC_mbedtls_Info[ccmWorkingContext_ptr->HashOperationMode]);
193         if (NULL == md_info) {
194             goto End;
195         }
196         mbedtls_md_init(&ccmWorkingContext_ptr->RsaHashCtx);
197         Error = mbedtls_md_setup(&ccmWorkingContext_ptr->RsaHashCtx, md_info, 0); // 0 = HASH, not HMAC
198         if (Error != 0) {
199             goto End;
200         }
201 
202         Error = mbedtls_md_starts(&ccmWorkingContext_ptr->RsaHashCtx);
203         if (Error != 0) {
204             goto End;
205         }
206 #else
207         Error = CC_HashInit(
208             ((CCHashUserContext_t *)((ccmWorkingContext_ptr->RsaHashCtxBuff))),
209             ccmWorkingContext_ptr->HashOperationMode);
210         if (Error != CC_OK)
211             goto End;
212 
213 #endif
214     }
215 
216 
217     /* Switch to appropriate PKCS1_version */
218     /*-------------------------------------*/
219     switch (PKCS1_ver) {
220     case CC_PKCS1_VER15:
221         ccmWorkingContext_ptr->PKCS1_Version=CC_PKCS1_VER15;
222         break;
223 
224     case CC_PKCS1_VER21:
225         /*Checking restriction of Salt Length ; Hash output size and the mosulus*/
226         if (ModulusSizeBytes < (uint32_t)(ccmWorkingContext_ptr->HASH_Result_Size*4 + SaltLen + 2)) {
227             Error = CC_RSA_PSS_ENCODING_MODULUS_HASH_SALT_LENGTHS_ERROR;
228             goto End;
229         }
230         ccmWorkingContext_ptr->PKCS1_Version=CC_PKCS1_VER21;
231         break;
232 
233     default:
234         Error = CC_RSA_PKCS1_VER_ARG_ERROR;
235         goto End;
236     }
237 
238     /*  Set MGF indication */
239     switch (MGF) {
240     case CC_PKCS1_MGF1:
241         ccmWorkingContext_ptr->MGF_2use = CC_PKCS1_MGF1;
242         break;
243     case CC_PKCS1_NO_MGF:
244         ccmWorkingContext_ptr->MGF_2use = CC_PKCS1_NO_MGF;
245         break;
246     default:
247         Error = CC_RSA_MGF_ILLEGAL_ARG_ERROR;
248         goto End;
249     }
250 
251     /* Copying the RSA Private key argument to the context*/
252     CC_PalMemCopy((uint8_t*)&ccmWorkingContext_ptr->PrivUserKey,
253         (uint8_t*)UserPrivKey_ptr, sizeof(CCRsaUserPrivKey_t));
254 
255     /*Initial the Salt random length relevant for PKCS#1 Ver2.1*/
256     ccmWorkingContext_ptr->SaltLen = SaltLen;
257 
258     /* Set the RSA tag to the users context */
259     UserContext_ptr->valid_tag = CC_RSA_SIGN_CONTEXT_VALIDATION_TAG;
260 
261 End:
262 
263     /* .... Clearing the users context in case of error ... */
264     if (Error != CC_OK) {
265 #ifdef USE_MBEDTLS_CRYPTOCELL
266         if(md_info!=NULL){
267                 mbedtls_md_free(&ccmWorkingContext_ptr->RsaHashCtx);
268         }
269 #endif
270         CC_PalMemSetZero(UserContext_ptr, sizeof(CCRsaPrivUserContext_t));
271     }
272 
273     return Error;
274 
275 }/* CC_RsaSignInit */
276 
277 /**********************************************************************************************************/
278 /**
279    \brief CC_RsaSignUpdate processes the data to be signed
280    in a given context.
281 
282    \note CC_RsaSignUpdate can be called multiple times
283    with data
284 
285    @param[in] UserContext_ptr - A pointer to a valid context,
286                 as returned by CC_RsaSignInit.
287    @param[in] DataIn_ptr - A pointer to the data to sign.
288    @param[in] DataInSize - The size, in bytes, of the data to sign.
289 
290    @return CCError_t - CC_OK, or error
291 */
292 
CC_RsaSignUpdate(CCRsaPrivUserContext_t * UserContext_ptr,uint8_t * DataIn_ptr,size_t DataInSize)293 CEXPORT_C CCError_t CC_RsaSignUpdate(CCRsaPrivUserContext_t *UserContext_ptr,
294                      uint8_t     *DataIn_ptr,
295                      size_t      DataInSize)
296 {
297     /* FUNCTION DECLERATIONS */
298 
299     /* The return error identifier */
300     CCError_t Error = CC_OK;
301 
302     /* defining a pointer to the active context allcated by the CCM */
303     RSAPrivContext_t *ccmWorkingContext_ptr;
304 
305     /* FUNCTION LOGIC */
306 
307     /* ....... aquiring the RSA context ........ */
308     ccmWorkingContext_ptr = (RSAPrivContext_t*)((void*)&UserContext_ptr->context_buff);
309 
310     /* ............... checking the parameters validity ................... */
311     /* -------------------------------------------------------------------- */
312 
313     /* if the users context pointer is NULL return an error */
314     if (UserContext_ptr == NULL){
315         return CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;
316     }
317 
318     /* if the users Data In pointer is illegal return an error */
319     if (DataIn_ptr == NULL && DataInSize) {
320         Error =  CC_RSA_DATA_POINTER_INVALID_ERROR;
321         goto End;
322     }
323 
324     /* if the data size is larger then 2^29 (to prevant an overflow on the transition to bits )
325        return error */
326     if (DataInSize >= (1 << 29)) {
327         Error =  CC_RSA_INVALID_MESSAGE_DATA_SIZE;
328         goto End;
329     }
330 
331     /* if the users context TAG is illegal return an error - the context is invalid */
332     if (UserContext_ptr->valid_tag != CC_RSA_SIGN_CONTEXT_VALIDATION_TAG) {
333         Error =  CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR;
334         goto End;
335     }
336 
337     if (ccmWorkingContext_ptr->doHash) {
338         /*Operate the Hash update function for relevant versions*/
339 #ifdef USE_MBEDTLS_CRYPTOCELL
340         Error = mbedtls_md_update(&ccmWorkingContext_ptr->RsaHashCtx, DataIn_ptr, DataInSize);
341         if ( Error != 0 )
342             goto End;
343 #else
344         Error=CC_HashUpdate( ((CCHashUserContext_t *)(ccmWorkingContext_ptr->RsaHashCtxBuff)),
345                     DataIn_ptr,
346                     DataInSize );
347         if (Error != CC_OK)
348             goto End;
349 #endif
350     } else {
351         /* DataInSize must fit exactly to the size of Hash output that we support */
352         if (DataInSize != ccmWorkingContext_ptr->HASH_Result_Size*sizeof(uint32_t)) {
353             Error = CC_RSA_INVALID_MESSAGE_DATA_SIZE_IN_SSL_CASE;
354             goto End;
355         }
356         /* Copy the DataIn_ptr to the HashResult in case it is an SSL mode*/
357         CC_PalMemCopy((uint8_t *)ccmWorkingContext_ptr->HASH_Result, DataIn_ptr, DataInSize);
358     }
359 
360 End:
361 
362     /* .... clearing the users context in case of error .... */
363     if (Error != CC_OK) {
364 #ifdef USE_MBEDTLS_CRYPTOCELL
365         mbedtls_md_free(&ccmWorkingContext_ptr->RsaHashCtx);
366 #endif
367         CC_PalMemSetZero(UserContext_ptr, sizeof(CCRsaPrivUserContext_t));
368     }
369 
370     return Error;
371 
372 
373 }/* CC_RsaSignUpdate */
374 
375 
376 /**********************************************************************************************************/
377 /**
378    \brief CC_RsaSignFinish calculates the signature on the
379    data passed to one or more calls to CC_RsaSignUpdate,
380    and releases the context.
381 
382    @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
383    @param[in,out] UserContext_ptr - A pointer to the Context
384                 initialized by the SignInit function
385                 and used by the SignUpdate function
386    @param[out] Output_ptr - A pointer to the signature.
387                 The buffer must be at least PrivKey_ptr->N.len bytes long
388                 (that is, the size of the modulus, in bytes).
389    @param[in,out] OutputSize_ptr - A pointer to the Signature Size value - the input value
390                    is the signature buffer size allocated, the output value is
391                    the signature size used.
392                    The buffer must be at least PrivKey_ptr->N.len bytes long
393                    (that is, the size of the modulus, in bytes).
394    @param[in] bIsRawMode - boolean to indicate if the function is used in Raw
395                            mode, which means that the structure T to be signed
396                            is passed as input (no need to perform hashing)
397    @param[in] DataIn_ptr - Buffer containing the T structure to be signed
398                            (possibly the DER encoding of ASN.1 DigestInfo
399                            structure as specified in RFC8017 sect. 9.2 notes)
400    @param[in] DataInSize - Size in bytes of the T structure passed as input in
401                            DataIn_ptr
402 
403    @return CCError_t - CC_OK,
404              CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR,
405              CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR,
406              CC_RSA_INVALID_OUTPUT_POINTER_ERROR,
407              CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE,
408              CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR,
409              CC_RSA_PKCS1_VER_ARG_ERROR
410 */
CC_RsaSignFinish(CCRndContext_t * rndContext_ptr,CCRsaPrivUserContext_t * UserContext_ptr,uint8_t * Output_ptr,size_t * OutputSize_ptr,bool bIsRawMode,const uint8_t * DataIn_ptr,size_t DataInSize)411 CEXPORT_C CCError_t CC_RsaSignFinish(
412                      CCRndContext_t *rndContext_ptr,
413                      CCRsaPrivUserContext_t *UserContext_ptr,
414                      uint8_t *Output_ptr,
415                      size_t *OutputSize_ptr,
416                      bool bIsRawMode,
417                      const uint8_t *DataIn_ptr,
418                      size_t DataInSize)
419 {
420     /* FUNCTION DECLERATIONS */
421 
422     /* The return error identifier */
423     CCError_t Error = CC_OK;
424     /* defining a pointer to the active context allocated by the CCM */
425     RSAPrivContext_t *ccmWorkingContext_ptr;
426     /*The modulus size in Octets*/
427     uint16_t K;
428     CCRsaPrivKey_t *PrivKey_ptr;
429 
430 
431     /* FUNCTION LOGIC */
432 
433     /* ................. aquiring the RSA context ............................. */
434     ccmWorkingContext_ptr = (RSAPrivContext_t*)((void*)&UserContext_ptr->context_buff);
435 
436     /* ............... checking the parameters validity ................... */
437     /* -------------------------------------------------------------------- */
438 
439     /* if the users context pointer is NULL return an error */
440     if (UserContext_ptr == NULL){
441         return CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR;
442     }
443 
444     /*If the output pointer is NULL return Error*/
445     if (Output_ptr == NULL) {
446         Error =  CC_RSA_INVALID_OUTPUT_POINTER_ERROR;
447         goto End1;
448     }
449 
450     /*If the output Size pointer is NULL return Error*/
451     if (OutputSize_ptr == NULL) {
452         Error =  CC_RSA_INVALID_OUTPUT_SIZE_POINTER_ERROR;
453         goto End1;
454     }
455 
456     /* if the users context TAG is illegal return an error - the context is invalid */
457     if (UserContext_ptr->valid_tag != CC_RSA_SIGN_CONTEXT_VALIDATION_TAG) {
458         Error =  CC_RSA_USER_CONTEXT_VALIDATION_TAG_ERROR;
459         goto End1;
460     }
461 
462 
463     /* ......... checking the validity of the prameters in the context ........ */
464     /* ------------------------------------------------------------------------ */
465 
466     PrivKey_ptr = (CCRsaPrivKey_t *)ccmWorkingContext_ptr->PrivUserKey.PrivateKeyDbBuff;
467 
468     /*Initializing the Modulus Size in Bytes*/
469     K =  (uint16_t)CALC_FULL_BYTES(PrivKey_ptr->nSizeInBits);
470 
471     /* If the received output buffer is small then return an error */
472     if (*OutputSize_ptr < K) {
473         Error = CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE;
474         goto End1;
475     }
476 
477     /*Operating the HASH Finish function only in case that Hash operation is needed*/
478     if (ccmWorkingContext_ptr->doHash) {
479 #ifdef USE_MBEDTLS_CRYPTOCELL
480         Error = mbedtls_md_finish(&ccmWorkingContext_ptr->RsaHashCtx,
481                                     (unsigned char *)ccmWorkingContext_ptr->HASH_Result);
482         if ( Error != 0 )
483             goto End;
484 #else
485         Error = CC_HashFinish(((CCHashUserContext_t *)(ccmWorkingContext_ptr->RsaHashCtxBuff)),
486                        ccmWorkingContext_ptr->HASH_Result);
487         if (Error != CC_OK)
488             goto End;
489 #endif
490     }
491     /* ........................... execute the signiture ........................... */
492     /* ----------------------------------------------------------------------------- */
493 
494     switch (ccmWorkingContext_ptr->PKCS1_Version) {
495 
496 #ifndef _INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT
497     case CC_PKCS1_VER21:
498 
499         Error = RsaPssSign21(rndContext_ptr, ccmWorkingContext_ptr, Output_ptr);
500         if (Error!=CC_OK)
501             goto End;
502         /* set the output size to the modulus size */
503         *OutputSize_ptr = K;
504         break;
505 #endif
506 
507 #ifndef _INTERNAL_CC_NO_RSA_SCHEME_15_SUPPORT
508     case CC_PKCS1_VER15:
509         /*The ouput size should be of the Modulus size = K*/
510         Error = RsaEmsaPkcs1v15Encode(
511                 K,
512                 ccmWorkingContext_ptr->HashOperationMode,
513                 (uint8_t*)ccmWorkingContext_ptr->HASH_Result,
514                 ccmWorkingContext_ptr->HASH_Result_Size*sizeof(uint32_t),
515                 (uint8_t*)ccmWorkingContext_ptr->EBD,
516                 bIsRawMode,
517                 DataIn_ptr,
518                 DataInSize);
519 
520         if (Error!=CC_OK)
521             goto End;
522 
523         /* ..........    execute RSA encryption   .......... */
524 
525         Error = CC_RsaPrimDecrypt(
526                 &ccmWorkingContext_ptr->PrivUserKey,
527                 &ccmWorkingContext_ptr->PrimeData,
528                 (uint8_t*)ccmWorkingContext_ptr->EBD,
529                 K, Output_ptr);
530 
531         if (Error!=CC_OK)
532             goto End;
533         /* set the output size to the modulus size */
534         *OutputSize_ptr = K;
535         break;
536 #endif
537     default:
538         Error = CC_RSA_PKCS1_VER_ARG_ERROR;
539         goto End;
540 
541     }/* end of (ccmWorkingContext_ptr->PKCS1_Version ) switch */
542 
543 End:
544     if(Error != CC_OK) {
545         CC_PalMemSetZero(Output_ptr, *OutputSize_ptr);
546         *OutputSize_ptr = 0;
547     }
548 
549 End1:
550 #ifdef USE_MBEDTLS_CRYPTOCELL
551     mbedtls_md_free(&ccmWorkingContext_ptr->RsaHashCtx);
552 #endif
553 
554     /* .... clearing the users context in case of error  ... */
555     CC_PalMemSetZero(UserContext_ptr,sizeof(CCRsaPrivUserContext_t));
556 
557     return Error;
558 
559 }/* CC_RsaSignFinish */
560 
561 
562 /**********************************************************************************************************/
563 /**
564    @brief
565    \brief RSA_Sign implements the RSASSA-PKCS1v15 algorithm
566     in a single function as defined in PKCS#1 v2.1 standard, including v1.5.
567 
568     The user can call the function by appropriate macro according to choosen
569     (and allowed) HASH algorithm SHA1, SHA224... (see macros below).
570 
571     NOTE: 1. In PSS_Sign v2.1 MD5 is not supported, since it is not recommended
572          by the PKCS#1 v2.1.
573           2. According to thesaid standard, implementation of the function
574          for version v1.5 is based on DER encoding of the algorithm info.
575 
576    @param[in/out] rndContext_ptr  - Pointer to the RND context buffer.
577    @param[in] UserContext_ptr - A pointer to a Context. For the use of the
578                                 function as a space to work on.
579    @param[in] UserPrivKey_ptr - A pointer to the private key data
580                             structure of the user. \note The representation
581                             (pair or quintuple) and hence the
582                             algorithm (CRT or not) is determined
583                             by the Private Key data
584                             structure - using CC_BuildPrivKey
585                             or CC_BuildPrivKeyCRT determines
586                             which algorithm will be used.
587    @param[in] hashFunc - The hash functions supported: SHA1, SHA-256/224/264/512, MD5
588                          (MD5 - allowed only for PKCS#1 v1.5).
589              Also allowed "After" HASH modes for said functions.
590    @param[in] MGF - The mask generation function (enum). Only for PKCS#1 v2.1
591                     defines MGF1, so the only value allowed for v2.1
592                     is CC_PKCS1_MGF1.
593    @param[in] SaltLen - The Length of the Salt buffer (relevant for PKCS#1 Ver 2.1 only)
594             Typical lengths are 0 and hLen (20 for SHA1)
595             The maximum length allowed is NSize - hLen - 2.
596    @param[in] DataIn_ptr - A pointer to the data to sign.
597    @param[in] DataInSize - The size, in bytes, of the data to sign.
598    @param[out] Output_ptr - A pointer to the signature.
599                             The buffer must be at least PrivKey_ptr->N.len bytes long
600                             (that is, the size of the modulus in bytes).
601    @param[in,out] OutputSize_ptr - A pointer to the Signature Size value - the input value
602                             is the signature buffer size allocated, the output value is
603                             the signature size actually used.
604                             The buffer must be at least PrivKey_ptr->N.len bytes long
605                             (that is, the size of the modulus in bytes).
606    @param[in] PKCS1_ver - Ver 1.5 or 2.1, according to the functionality required
607 
608    @return CCError_t - CC_OK,
609                          CC_RSA_INVALID_USER_CONTEXT_POINTER_ERROR,
610                          CC_RSA_INVALID_PRIV_KEY_STRUCT_POINTER_ERROR,
611                          CC_RSA_PRIV_KEY_VALIDATION_TAG_ERROR,
612                          CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR,
613                          CC_RSA_MGF_ILLEGAL_ARG_ERROR,
614                          CC_RSA_PKCS1_VER_ARG_ERROR,
615                          CC_RSA_INVALID_MESSAGE_DATA_SIZE,
616                          CC_RSA_INVALID_OUTPUT_POINTER_ERROR,
617                          CC_RSA_INVALID_SIGNATURE_BUFFER_SIZE
618 */
CC_RsaSign(CCRndContext_t * rndContext_ptr,CCRsaPrivUserContext_t * UserContext_ptr,CCRsaUserPrivKey_t * UserPrivKey_ptr,CCRsaHashOpMode_t rsaHashMode,CCPkcs1Mgf_t MGF,size_t SaltLen,uint8_t * DataIn_ptr,size_t DataInSize,uint8_t * Output_ptr,size_t * OutputSize_ptr,CCPkcs1Version_t PKCS1_ver)619 CEXPORT_C CCError_t CC_RsaSign(
620                    CCRndContext_t *rndContext_ptr,
621                    CCRsaPrivUserContext_t *UserContext_ptr,
622            CCRsaUserPrivKey_t *UserPrivKey_ptr,
623            CCRsaHashOpMode_t rsaHashMode,
624            CCPkcs1Mgf_t MGF,
625            size_t       SaltLen,
626            uint8_t     *DataIn_ptr,
627            size_t       DataInSize,
628            uint8_t     *Output_ptr,
629            size_t      *OutputSize_ptr,
630            CCPkcs1Version_t PKCS1_ver)
631 
632 {
633     /* FUNCTION DECLARATIONS */
634 
635     /* The return error identifier */
636     CCError_t Error = CC_OK;
637     bool bIsRawMode = (rsaHashMode == CC_RSA_HASH_NO_HASH_mode) ? true : false;
638 
639     /* FUNCTION LOGIC */
640 
641     CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
642 
643     /**********************************************************************
644      *  RSA_SignInit
645      **********************************************************************/
646     Error = CC_RsaSignInit( UserContext_ptr,
647                   UserPrivKey_ptr,
648                   rsaHashMode,
649                   MGF,
650                   SaltLen,
651                   PKCS1_ver);
652     if (Error!=CC_OK)
653         return Error;
654     /**********************************************************************
655      *  RSA_SignUpdate
656      **********************************************************************/
657     if (!bIsRawMode) {
658         Error = CC_RsaSignUpdate(UserContext_ptr,
659                        DataIn_ptr,
660                        DataInSize);
661         if (Error!=CC_OK)
662             return Error;
663     }
664     /**********************************************************************
665      * RSA_SignFinish
666      **********************************************************************/
667     Error = CC_RsaSignFinish(
668                    rndContext_ptr,
669                    UserContext_ptr,
670                    Output_ptr,
671                    OutputSize_ptr,
672                    bIsRawMode,
673                    DataIn_ptr,
674                    DataInSize);
675     return Error;
676 
677 }/* END OF CC_RsaSign */
678 
679 #endif /*_INTERNAL_CC_NO_RSA_SIGN_SUPPORT*/
680 #endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
681