1 /*
2  * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #ifdef CC_IOT
7 #include "mbedtls/build_info.h"
8 #endif
9 
10 #if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
11 /************* Include Files ****************/
12 #include "cc_pal_mem.h"
13 #include "cc_pal_types.h"
14 #include "cc_common_math.h"
15 #include "cc_rsa_error.h"
16 #ifndef USE_MBEDTLS_CRYPTOCELL
17 #include "cc_hash.h"
18 #endif
19 #include "cc_hash_defs.h"
20 #include "cc_rsa_local.h"
21 #include "cc_rnd_error.h"
22 #include "cc_general_defs.h"
23 
24 /************************ Defines ****************************/
25 
26 /************************ Enums ******************************/
27 
28 /************************ Typedefs ***************************/
29 
30 /************************ Global Data *************************/
31 
32 #ifdef DEBUG_OAEP_SEED
33 #include "CRYS_RSA_PSS21_defines.h"
34 extern uint8_t SaltDB[NUM_OF_SETS_TEST_VECTORS][NUM_OF_TEST_VECTOR_IN_SET][CC_RSA_PSS_SALT_LENGTH];
35 extern uint16_t Global_Set_Index;
36 extern uint16_t Global_vector_Index;
37 #endif
38 
39 /************* Private function prototype ****************/
40 
41 
42 
43 #if !defined(_INTERNAL_CC_NO_RSA_ENCRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)
44 /************************ Public Functions ******************************/
45 /**
46    @brief
47    RsaPssOaepEncode implements the the Encoding operation according to the PKCS#1 as defined
48    in PKCS#1 v2.1 7.1.1 (2) and PKCS#1 v2.0
49 */
RsaPssOaepEncode(CCRndContext_t * rndContext_ptr,CCPkcs1HashFunc_t hashFunc,CCPkcs1Mgf_t MGF,uint8_t * M_ptr,uint16_t MSize,uint8_t * P_ptr,size_t PSize,uint16_t emLen,CCRsaPrimeData_t * PrimeData_ptr,uint8_t * EMInput_ptr,CCPkcs1Version_t PKCS1_ver)50 CCError_t RsaPssOaepEncode(
51                                    CCRndContext_t *rndContext_ptr, /* random functions context */
52                                    CCPkcs1HashFunc_t hashFunc,     /* PKCS1 hash mode enum */
53                                    CCPkcs1Mgf_t MGF,               /* MGF function type enum */
54                                    uint8_t *M_ptr,                     /* a pointer to the message to be encoded */
55                                    uint16_t MSize,                     /* the message size in bytes */
56                                    uint8_t *P_ptr,                     /* a pointer to the label; can be empty string */
57                                    size_t   PSize,                     /* the size of the label in bytes */
58                                    uint16_t emLen, /* The value is set before the call */
59                                    CCRsaPrimeData_t  *PrimeData_ptr,/* temp buffer */
60                                    uint8_t  *EMInput_ptr,              /* encoded message output */
61                                    CCPkcs1Version_t PKCS1_ver)
62 {
63 
64         /* FUNCTION DECLARATIONS */
65 
66         /* The return error identifier */
67         CCError_t Error = CC_OK;
68 
69         /*For PKCS1 Ver21 standard: emLen = k = Public mod N size*/
70         /*Used for output of MGF1 function ; the size is at most emLen */
71         uint8_t *MaskDB_Ptr =((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->MaskDB;
72         uint32_t HashOutputSize;
73         uint16_t TmpSize, I;
74         uint8_t *TmpByte_ptr;
75         uint8_t *EM_ptr = &EMInput_ptr[1];
76         uint8_t VersionConstant;   /*Used to distinguish between Ver 2.1 and others for some memory manipulations*/
77 
78 #ifdef DEBUG_OAEP_SEED
79         uint8_t *SeedTEST = SaltDB[Global_Set_Index][Global_vector_Index]; /*A Data Base created in the test file for checking the Encrypted operation*/
80 #endif/*otherwise the seed is generated strait to EM_ptr*/
81 
82 #ifdef USE_MBEDTLS_CRYPTOCELL
83         const mbedtls_md_info_t *md_info=NULL;
84         mbedtls_md_context_t *md_ctx=NULL;
85 #endif
86 
87         void   *rndState_ptr;
88         CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
89 
90         /* FUNCTION LOGIC */
91 
92         /* check parameters */
93         if (rndContext_ptr == NULL)
94                 return CC_RND_CONTEXT_PTR_INVALID_ERROR;
95 
96         rndState_ptr = (rndContext_ptr->rndState);
97         RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
98 
99         if (RndGenerateVectFunc == NULL)
100                 return CC_RND_GEN_VECTOR_FUNC_ERROR;
101 
102         /* .................. initializing local variables ................... */
103         /* ------------------------------------------------------------------- */
104 
105         /*Initializing the first Byte to Zero*/
106         EMInput_ptr[0] = 0;
107 
108         /* get HASH output size */
109         switch (hashFunc) {
110         case CC_HASH_MD5_mode :
111                 HashOutputSize = CC_HASH_MD5_DIGEST_SIZE_IN_BYTES;
112                 break;
113         case CC_HASH_SHA1_mode:
114                 HashOutputSize = CC_HASH_SHA1_DIGEST_SIZE_IN_BYTES;
115                 break;
116         case CC_HASH_SHA224_mode:
117                 HashOutputSize = CC_HASH_SHA224_DIGEST_SIZE_IN_BYTES;
118                 break;
119         case CC_HASH_SHA256_mode:
120                 HashOutputSize = CC_HASH_SHA256_DIGEST_SIZE_IN_BYTES;
121                 break;
122         case CC_HASH_SHA384_mode:
123                 HashOutputSize = CC_HASH_SHA384_DIGEST_SIZE_IN_BYTES;
124                 break;
125         case CC_HASH_SHA512_mode:
126                 HashOutputSize = CC_HASH_SHA512_DIGEST_SIZE_IN_BYTES;
127                 break;
128         default:
129                 return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
130         }
131         // RL Version = 2
132         if (PKCS1_ver == CC_PKCS1_VER21)
133                 VersionConstant = 2;
134         else
135                 VersionConstant = 1;
136 
137 /*------------------------------------------------------------*
138  * Step 1 : If the length of P is greater than                *
139  *           the input limitation for the hash                *
140  *           function (2^29 octets for SHA-1)                 *
141  *           then output "parameter string too long" and stop *
142  *                                                            *
143  *           In PKCS1_Ver2.1 L = P                            *
144  *------------------------------------------------------------*/
145 
146 /* if the P  larger then 2^29 which is the input limitation for HASH
147    return error (to prevent an overflow on the transition to bits ) */
148         if (PSize >= (1 << 29))
149                 return CC_RSA_BASE_OAEP_ENCODE_PARAMETER_STRING_TOO_LONG;
150 
151 /*-------------------------------------------------*
152  * Step 2 : If ||M|| > emLen-2hLen-1 then output   *
153  *   "message too long" and stop.                  *
154  *                                                 *
155  * for PKCS1_Ver2.1 Step 1 <b>:            *
156  * If ||M|| > emLen - 2hLen - 2                    *
157  *-------------------------------------------------*/
158 
159         if ((uint32_t)MSize + 2 * HashOutputSize + VersionConstant > emLen)
160                 return CC_RSA_BASE_OAEP_ENCODE_MESSAGE_TOO_LONG;
161 
162 /*-----------------------------------------------------*
163  * Step 3 : Generate an octet string PS consisting of  *
164  *           emLen-||M||-2hLen-1 zero octets.          *
165  *           The length of PS may be 0.                *
166  *                                                     *
167  * PKCS1_VER21 Step 2 <b>                  *
168  *       Generate an octet string PS consisting of *
169  *           emLen-||M||-2hLen-2 zero octets.          *
170  *           The length of PS may be 0                 *
171  *-----------------------------------------------------*/
172         CC_PalMemSetZero((uint8_t*)&EM_ptr[2*HashOutputSize], emLen-MSize-2*HashOutputSize-VersionConstant);
173 
174 /*--------------------------------------------------------------*
175  * Step 4 : Let pHash = Hash(P), an octet string of length hLen.*
176  * PKCS1_VER21 Step 2 <a> where L is denoted by P and usually   *
177  * an empty string                                              *
178  *--------------------------------------------------------------*/
179         if (P_ptr!=NULL) {
180 #ifdef USE_MBEDTLS_CRYPTOCELL
181                 md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashFunc] );
182                 if (NULL == md_info) {
183                      return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
184                 }
185                 Error = mbedtls_md(md_info,
186                                    P_ptr,
187                                    PSize,
188                                    (unsigned char *)((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
189  #else
190                 Error=CC_Hash( hashFunc,
191                                  P_ptr,
192                                  PSize,
193                                  ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
194 #endif
195                 if (Error!=CC_OK) {
196                         goto End;
197                 }
198         } else {/* if empty string */
199 #ifdef USE_MBEDTLS_CRYPTOCELL
200                 md_ctx = &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->hash_ctx);
201                 md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashFunc] );
202                 if (NULL == md_info) {
203                         return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
204                 }
205                 mbedtls_md_init(md_ctx);
206                 Error = mbedtls_md_setup(md_ctx, md_info, 0); // 0 = HASH, not HMAC
207                 if (Error != 0) {
208                         goto End;
209                 }
210                 Error = mbedtls_md_starts(md_ctx);
211 #else
212                 Error=CC_HashInit(&(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashUsercontext),
213                                      hashFunc);
214 #endif
215                 if (Error!=CC_OK) {
216                         goto End;
217                 }
218 #ifdef USE_MBEDTLS_CRYPTOCELL
219                 Error = mbedtls_md_finish(md_ctx, (unsigned char *)((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
220 #else
221                 Error=CC_HashFinish( &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashUsercontext) ,
222                                         ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
223 #endif
224                 if (Error!=CC_OK) {
225                         goto End;
226                 }
227         }
228         /*Copy the Hash result to the proper place in the output buffer*/
229         CC_PalMemCopy(&EM_ptr[HashOutputSize], (uint8_t *)(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff), HashOutputSize);
230 
231 /*---------------------------------------------------------*
232  * Step 5 : Concatenate pHash, PS, the message M,          *
233  *           and other padding to form a data block DB     *
234  * PKCS1_VER21 Step 2 <c>                                  *
235  *      Concatenate pHash, PS, the message M,              *
236  *       and other padding to form a data block DB as      *
237  *       DB = pHash || PS || 01 || M                       *
238  *---------------------------------------------------------*/
239         /* EM_ptr[emLen-MSize-1]=0x01;*/
240         EM_ptr[emLen - MSize - 1 - (VersionConstant-1)] = 0x01;/*because emLen = PubNSize; but EM_ptr points to place 1*/
241     if (MSize > 0) // need to copy only if there is data
242         CC_PalMemCopy((uint8_t*)&EM_ptr[emLen - MSize - (VersionConstant - 1)], M_ptr, MSize);/*because emLen = PubNSize; but EM_ptr points to place 1 */
243 
244 /*--------------------------------------------------------------*
245  * Step 6 : Generate a random octet string seed of length hLen. *
246  * PKCS1_VER21 Step 2.d: Generate a random octet string seed    *
247  *                       of length hLen.                        *
248  *--------------------------------------------------------------*/
249 
250 #ifdef DEBUG_OAEP_SEED
251         /*Only for PKCS#1 ver2.1 SHA1 - Salt length is 20*/
252         CC_PalMemCopy(EM_ptr, SeedTEST,CC_RSA_PSS_SALT_LENGTH);
253 #else
254         Error = RndGenerateVectFunc(rndState_ptr, (unsigned char *)EM_ptr, (size_t)HashOutputSize);
255         if (Error != CC_OK) {
256                 goto End;
257         }
258 
259 #endif
260 
261 /*-----------------------------------------------*
262  * Step 7 : Let dbMask = MGF(seed, emLen-hLen).  *
263  * PKCS1_VER21 Step 2 <e> Let                    *
264  *      dbMask = MGF(seed, emLen-hLen-1).        *
265  *-----------------------------------------------*/
266 
267         switch (MGF) {
268         case CC_PKCS1_MGF1:
269 
270                 Error = RsaOaepMGF1(
271                                          HashOutputSize,                                                          /*hashLen*/
272                                          &EM_ptr[0],                                                              /*mgfSeed*/
273                                          HashOutputSize,                                                          /*seedLen*/
274                                          emLen-HashOutputSize-(VersionConstant-1),                                /*maskLen*/
275                                          &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->MaskDB[0]), /*mask*/
276                                          hashFunc,                                                                /*hashMode*/
277                                          (uint8_t *)PrimeData_ptr->DataIn,                                        /*1-st tempBuff*/
278                                          (uint8_t *)PrimeData_ptr->DataOut);                                      /*2-nd tempBuff*/
279 
280                 if (Error != CC_OK) {
281                         goto End;
282                 }
283                 break;
284 
285         /*Currently for PKCS1 Ver 2.1 only MGF1 is implemented*/
286         case CC_PKCS1_NO_MGF:
287         default:
288                 Error = CC_RSA_MGF_ILLEGAL_ARG_ERROR;
289                 goto End;
290         }
291 
292         /*----------------------------------------------*
293         *  Step 8 : PKCS1_VER21 Step 2.f:               *
294         *             Let maskedDB = DB xor dbMask.     *
295         *-----------------------------------------------*/
296 
297         TmpSize = emLen - HashOutputSize - (VersionConstant - 1);
298         TmpByte_ptr = &EM_ptr[HashOutputSize];
299         for (I = 0; I < TmpSize; I++)
300                 *(TmpByte_ptr + I) ^= ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->MaskDB[I];
301 
302         MaskDB_Ptr = TmpByte_ptr;
303 
304 /*-----------------------------------------------*
305  * Step 9 : Let seedMask = MGF(maskedDB, hLen).  *
306  * PKCS1_VER21 Step 2.g                          *
307  *-----------------------------------------------*/
308 
309         switch (MGF) {
310         case CC_PKCS1_MGF1:
311 
312                 Error = RsaOaepMGF1(
313                                  HashOutputSize, /* This is important its uint32 as a result of size limits */
314                                  MaskDB_Ptr,
315                                  (uint16_t)(emLen-HashOutputSize-(VersionConstant-1)),
316                                  HashOutputSize,
317                                  &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->SeedMask[0]),
318                                  hashFunc,
319                                  (uint8_t *)PrimeData_ptr->DataIn,
320                                  (uint8_t *)PrimeData_ptr->DataOut);
321 
322                 if (Error != CC_OK)
323                         goto End;
324 
325                 break;
326 
327                 /*Currently for PKCS1 Ver 2.1 only MGF1 is implemented*/
328         case CC_PKCS1_NO_MGF:
329         default:
330                 Error = CC_RSA_MGF_ILLEGAL_ARG_ERROR;
331                 goto End;
332 
333         }/* end of MGF type switch */
334 
335 /*-----------------------------------------------*
336  * Step 10: Let maskedSeed = seed \xor seedMask. *
337  * PKCS1_VER21 Step 2 <h>                        *
338  *-----------------------------------------------*/
339 
340         TmpSize = HashOutputSize;
341         TmpByte_ptr =& EM_ptr[0];
342         for (I = 0;I < TmpSize; I++)
343                 *(TmpByte_ptr + I)^=((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->SeedMask[I];
344 
345 /*---------------------------------------------*
346  *  * Step 11:  PKCS1_VER21 Step 2.i:          *
347  * Let EM = 0x00 || maskedSeed || maskedDB.    *
348  * This step is done !                         *
349  *---------------------------------------------*/
350 
351         End:
352 #ifdef USE_MBEDTLS_CRYPTOCELL
353         if((md_info!=NULL) && (md_ctx!=NULL)) {
354                 mbedtls_md_free(md_ctx);
355         }
356 #endif
357         /*Clear Internal buffers*/
358         CC_PalMemSetZero((PrimeData_ptr->InternalBuff), sizeof(PrimeData_ptr->InternalBuff));
359         return Error;
360 
361 }
362 #endif /* !defined(CC_NO_RSA_ENCRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)*/
363 
364 #if !defined(CC_NO_RSA_DECRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_SIGN_SUPPORT)
365 
366 /**
367    @brief
368    RsaPssOaepDecode implements the Decoding operation according to the
369    PKCS#1 as defined in PKCS#1 v2.1 and PKCS#1 v2.0
370 */
RsaPssOaepDecode(CCPkcs1HashFunc_t hashFunc,CCPkcs1Mgf_t MGF,uint8_t * EM_ptr,uint16_t EMSize,uint8_t * P_ptr,size_t PSize,CCRsaPrimeData_t * PrimeData_ptr,uint8_t * M_ptr,size_t * MSize_ptr)371 CCError_t RsaPssOaepDecode(
372                                    CCPkcs1HashFunc_t hashFunc,
373                                    CCPkcs1Mgf_t MGF,
374                                    uint8_t  *EM_ptr,
375                                    uint16_t EMSize,
376                                    uint8_t *P_ptr,
377                                    size_t  PSize,
378                                    CCRsaPrimeData_t  *PrimeData_ptr, /*Only for stack memory save*/
379                                    uint8_t *M_ptr,
380                                    size_t  *MSize_ptr)
381 {
382         /* FUNCTION DECLERATIONS */
383 
384         uint8_t HashOutputSize;
385         /* The return error identifier */
386         CCError_t Error = CC_OK;
387         uint8_t  *maskedDB_ptr;
388         uint16_t  I, TmpSize;
389         uint8_t  *TmpByte_ptr;
390 #ifdef USE_MBEDTLS_CRYPTOCELL
391         const mbedtls_md_info_t *md_info=NULL;
392         mbedtls_md_context_t *md_ctx=NULL;
393 #endif
394 
395         /* FUNCTION LOGIC */
396 
397         /* .................. initializing local variables ................... */
398         /* ------------------------------------------------------------------- */
399 
400         /* get hash output size */
401         switch (hashFunc) {
402         case CC_HASH_MD5_mode : /*MD5 is not recomended in PKCS1 ver 2.1 standard,
403                                     henceit is not supported */
404                 return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
405         case CC_HASH_SHA1_mode:
406                 HashOutputSize = CC_HASH_SHA1_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
407                 break;
408         case CC_HASH_SHA224_mode:
409                 HashOutputSize = CC_HASH_SHA224_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
410                 break;
411         case CC_HASH_SHA256_mode:
412                 HashOutputSize = CC_HASH_SHA256_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
413                 break;
414         case CC_HASH_SHA384_mode:
415                 HashOutputSize = CC_HASH_SHA384_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
416                 break;
417         case CC_HASH_SHA512_mode:
418                 HashOutputSize = CC_HASH_SHA512_DIGEST_SIZE_IN_WORDS*CC_32BIT_WORD_SIZE;
419                 break;
420         default:
421                 return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
422         }
423 
424 /*For PKCS1 Ver 2.1 P=L*/
425 /*--------------------------------------------------------*
426  * Step 1: if the length of P is greater than the input   *
427  *         limitation of the hash function (2^29 octets *
428  *         for SHA-1) then output "decoding error"        *
429  *          and stop.                                     *
430  *--------------------------------------------------------*/
431         if (PSize >= (1 << 29))
432                 return CC_RSA_BASE_OAEP_DECODE_PARAMETER_STRING_TOO_LONG;
433 
434 /*-------------------------------------------------------*
435  * Step 2: If ||EM|| < 2hLen+2, then output              *
436  *        "decoding error" and stop.                     *
437  *        Note: There EMSize = ||EM|| - 1                *
438  *-------------------------------------------------------*/
439         if (EMSize <  2*HashOutputSize + 1)
440                 return CC_RSA_BASE_OAEP_DECODE_MESSAGE_TOO_LONG;
441 /*-------------------------------------------------------*
442  * Step 3: Let maskedSeed be the first hLen octets of EM *
443  *         and let maskedDB be the remaining             *
444  *         ||EM|| - hLen octets.                         *
445  * PKCS1 Ver2.1: Step <3> <b>                            *
446  *-------------------------------------------------------*/
447         maskedDB_ptr = EM_ptr + HashOutputSize;
448 
449 /*-------------------------------------------------------*
450  * Step 4: Let seedMask = MGF(maskedDB, hLen).           *
451  * PKCS1 Ver2.1: Step <3> <c>                            *
452  *-------------------------------------------------------*/
453 
454         switch (MGF) {
455         case CC_PKCS1_MGF1:
456 
457                 Error = RsaOaepMGF1(
458                                          HashOutputSize,                                                             /*hashLen*/
459                                          maskedDB_ptr,                                                               /*mgfSeed - in*/
460                                          (uint16_t)(EMSize - HashOutputSize),                                        /*seedLen*/
461                                          HashOutputSize,                                                             /*maskLen*/
462                                          &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->SeedMask[0]),  /*mask - out*/
463                                          hashFunc,                                                                   /*hashMode*/
464                                          (uint8_t *)PrimeData_ptr->DataIn,                                           /*1-st tempBuff*/
465                                          (uint8_t *)PrimeData_ptr->DataOut);                                         /*2-nd tempBuff*/
466                 if (Error != CC_OK) {
467                         return Error;
468                 }
469                 break;
470 
471         /*Currently for PKCS1 Ver 2.1 only MGF1 is implemented*/
472         case CC_PKCS1_NO_MGF:
473         default:
474                 return CC_RSA_MGF_ILLEGAL_ARG_ERROR;
475 
476         }
477 
478 /*-------------------------------------------------------*
479  * Step 5: Let seed = maskedSeed xor seedMask.           *
480  * PKCS1 Ver2.1: Step <3> <d>                            *
481  *-------------------------------------------------------*/
482         for (I = 0; I < HashOutputSize; I++)
483                 EM_ptr[I] ^= ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->SeedMask[I];
484 
485 /*-------------------------------------------------------*
486  * Step 6: Let dbMask = MGF(seed, ||EM|| - hLen).        *
487  * PKCS1 Ver2.1: Step <3> <e>                            *
488  *-------------------------------------------------------*/
489         Error=RsaOaepMGF1(
490                                HashOutputSize,
491                                EM_ptr,
492                                HashOutputSize,
493                                EMSize - HashOutputSize,
494                                &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->MaskDB[0]),
495                                hashFunc,
496                                (uint8_t *)PrimeData_ptr->DataIn,
497                                (uint8_t *)PrimeData_ptr->DataOut);
498 
499         if (Error!=CC_OK)
500                 return Error;
501 
502 /*-------------------------------------------------------*
503  * Step 7: Let DB = maskedDB xor dbMask.                 *
504  *         PKCS1 Ver2.1: Step <3> <f>                    *
505  *-------------------------------------------------------*/
506         TmpSize = EMSize - HashOutputSize;
507         TmpByte_ptr = &EM_ptr[0] + HashOutputSize;
508         for (I = 0; I < TmpSize; I++)
509                 TmpByte_ptr[I] ^= ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->MaskDB[I];
510 
511 /*-------------------------------------------------------*
512  * Step 8: Let pHash = Hash(P), an octet string of       *
513  *         length hLen.                                  *
514  *                                                       *
515  * PKCS1 Ver2.1: Step <3> <a>                            *
516  *-------------------------------------------------------*/
517         if (P_ptr!=NULL) {
518 #ifdef USE_MBEDTLS_CRYPTOCELL
519                 md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashFunc] );
520                 if (NULL == md_info)
521                 {
522                     return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
523                 }
524                 Error = mbedtls_md(md_info,
525                                    P_ptr,
526                                    PSize,
527                                    (unsigned char *)((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
528 #else
529                 Error = CC_Hash(
530                                  hashFunc,
531                                  P_ptr,
532                                  PSize,
533                                  ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
534 #endif
535                 if (Error!=CC_OK) {
536                         return Error;
537                 }
538         } else {
539 #ifdef USE_MBEDTLS_CRYPTOCELL
540                 md_ctx = &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->hash_ctx);
541                 md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashFunc] );
542                 if (NULL == md_info) {
543                         return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
544                 }
545                 mbedtls_md_init(md_ctx);
546                 Error = mbedtls_md_setup(md_ctx, md_info, 0); // 0 = HASH, not HMAC
547                 if (Error != 0) {
548                         goto End;
549                 }
550                 Error = mbedtls_md_starts(md_ctx);
551 #else
552                 Error=CC_HashInit(&(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashUsercontext),
553                                   hashFunc);
554 #endif
555                 if (Error!=CC_OK) {
556                         goto End;
557                 }
558 #ifdef USE_MBEDTLS_CRYPTOCELL
559                 Error = mbedtls_md_finish(md_ctx, (unsigned char *)((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
560 #else
561                 Error=CC_HashFinish( &(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashUsercontext),
562                                         ((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff);
563 #endif
564                 if (Error!=CC_OK) {
565                         goto End;
566                 }
567         }
568 
569 
570 /*---------------------------------------------------------*
571  * Step 9: Separate DB into an octet string pHash'         *
572  *         consisting of the first hLen octets of DB,      *
573  *         a (possibly empty) octet string PS consisting   *
574  *         of consecutive zero octets following pHash',    *
575  *         and a message M as DB = pHash' || PS || 01 || M *
576  *         If there is no 01 octet to separate PS from M,  *
577  *         output "decoding error" and stop.               *
578  *                                                         *
579  * PKCS1 Ver2.1: Step <3> <g>                              *
580  *---------------------------------------------------------*/
581         TmpSize = EMSize - 2*HashOutputSize;
582         TmpByte_ptr = &EM_ptr[0] + 2*HashOutputSize;
583         for (I = 0; I < TmpSize; I++) {
584                 if (TmpByte_ptr[I] != 0x00)
585                         break;
586         }
587 
588         if (TmpByte_ptr[I] != 0x01){
589                 Error = CC_RSA_OAEP_DECODE_ERROR;
590                 goto End;
591         }
592 
593         TmpByte_ptr += I;
594 
595 /*------------------------------------------------------*
596  * Step 10: If pHash' does not equal pHash, output      *
597  *          "decoding error" and stop.                  *
598  *                                                      *
599  * PKCS1 Ver2.1: Step <3> <g>                           *
600  *------------------------------------------------------*/
601         if (CC_PalMemCmp(&EM_ptr[0] + HashOutputSize,
602                         (uint8_t *)(((CCRsaOaepData_t*)((void*)PrimeData_ptr->InternalBuff))->HashResultBuff),
603                         HashOutputSize)) {
604                 Error = CC_RSA_OAEP_DECODE_ERROR;
605                 goto End;
606         }
607 
608 /*-----------------------------------------------*
609  * Step 11: Output M.                            *
610  *-----------------------------------------------*/
611         /*Checking that the Output buffer Size is enough large for result output */
612         if (*MSize_ptr < (uint32_t)(EMSize - 2*HashOutputSize - I - 1)) {
613                 Error = CC_RSA_DECRYPT_INVALID_OUTPUT_SIZE;
614                 goto End;
615         }
616 
617         else if (*MSize_ptr > (uint32_t)(EMSize - 2*HashOutputSize - I - 1)) {
618                 /* set the actual output message size */
619                 *MSize_ptr = EMSize - 2*HashOutputSize - I - 1;
620         }
621 
622         /* at this point TmpByte_ptr points to 01 */
623         TmpByte_ptr += 1;
624 
625         /* at this point TmpByte_ptr points to M  */
626         CC_PalMemCopy( M_ptr, TmpByte_ptr, *MSize_ptr );
627 
628         End:
629 #ifdef USE_MBEDTLS_CRYPTOCELL
630         if((md_info!=NULL) && (md_ctx!=NULL)) {
631                 mbedtls_md_free(md_ctx);
632         }
633 #endif
634 
635         /*Clear Internal buffers*/
636         CC_PalMemSetZero((PrimeData_ptr->InternalBuff), sizeof(PrimeData_ptr->InternalBuff));
637 
638         return Error;
639 
640 }
641 #endif /*!defined(CC_NO_RSA_DECRYPT_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_SIGN_SUPPORT)*/
642 
643 
644 /**********************************************************************************************************/
645 
646 /* -------------------------------------------------------------
647  *  Function Name: RsaOaepMGF1
648  *  Date:   09-1-2005
649  *  Author: Ohad Shperling
650  *
651  *  Inputs:
652  *  Outputs:
653  *
654  *  Algorithm: according to PKCS1-v.2_1
655  *
656  *  Update History:
657  *  Date:       Description:
658  * ----------------------------------------------------------- */
RsaOaepMGF1(uint16_t hLen,uint8_t * Z_ptr,uint16_t ZSize,uint32_t L,uint8_t * Mask_ptr,CCPkcs1HashFunc_t hashFunc,uint8_t * T_Buf,uint8_t * T_TMP_Buf)659 CCError_t RsaOaepMGF1( uint16_t hLen,                  /*hashLen*/
660                                uint8_t *Z_ptr,                 /*mgfSeed*/
661                                uint16_t ZSize,                 /*seedLen*/
662                                uint32_t L,                     /*maskLen*/
663                                uint8_t  *Mask_ptr,             /*mask*/
664                                CCPkcs1HashFunc_t hashFunc, /*hashMode*/
665                                uint8_t  *T_Buf,                /*1-st tempBuff*/
666                                uint8_t  *T_TMP_Buf)            /*2-nd tempBuff*/
667 {
668 
669         /* FUNCTION DECLARATIONS */
670 
671         CCError_t Error;
672         uint32_t Counter = 0;
673         uint32_t CounterMaxSize, Tmp32Bit;
674         CCHashResultBuf_t  HashResultBuff;
675         uint8_t *Output_ptr;
676         uint8_t *T = T_Buf;/*The size of T for MGF1 used to be 2048/8 now the size of T_Buf in the context is even bigger*/
677         uint8_t *T_TMP = T_TMP_Buf;
678 #ifdef USE_MBEDTLS_CRYPTOCELL
679         const mbedtls_md_info_t *md_info=NULL;
680 #endif
681 
682 
683 /*---------------------------------------------------------------------*
684  * Step 1:  If l > 2^32 hLen, output "mask too long" and stop.          *
685  *---------------------------------------------------------------------*/
686 
687         /* note: check L > (uint32_t)(CC_RSA_MGF_2_POWER_32 *hLen) not needed
688                  because next check is more stronger */
689 
690         /* limit the size to the temp buffer size that is the maximum key length */
691         if (L > CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS * sizeof(uint32_t))
692                 return CC_RSA_BASE_MGF_MASK_TOO_LONG ;
693 
694 /*---------------------------------------------------------------------*
695  * Step 2:  Let T  be the empty octet string.                          *
696  *---------------------------------------------------------------------*/
697 
698 /*---------------------------------------------------------------------*
699  * Step 3:  For counter from 0 to  | l / hLen | -1 , do the following: *
700  *          a.  Convert counter to an octet string C of length 4       *
701  *              with the primitive I2OSP:                              *
702  *               C = I2OSP (counter, 4)                                *
703  *          b.  Concatenate the hash of the seed Z and C to the octet  *
704  *               string T:   T = T || Hash (Z || C)                    *
705  *---------------------------------------------------------------------*/
706         Output_ptr = T;
707         CC_PalMemCopy(T_TMP, Z_ptr/*seed*/, ZSize);
708 
709         /* count of Hash blocks needed for mask calculation */
710         CounterMaxSize = (uint32_t)((L + hLen - 1)/hLen);
711 
712         for (Counter = 0; Counter < CounterMaxSize; Counter++) {
713 
714                 /*--------------------------------------------------------------------
715                  *          a.  Convert counter to an octet string C of length 4
716                  *              with the primitive I2OSP:   C = I2OSP (counter, 4)
717                  *--------------------------------------------------------------------*/
718 
719                 /* T_TMP = H||C */
720 
721 #ifndef BIG__ENDIAN
722                 Tmp32Bit = CC_COMMON_REVERSE32(Counter);
723 #else
724                 Tmp32Bit = Counter;
725 #endif
726 
727                 CC_PalMemCopy(&T_TMP[0] + ZSize, &Tmp32Bit, sizeof(uint32_t));
728 
729                 /*--------------------------------------------------------------------
730                  *          b.  Concatenate the hash of the seed Z and C to the octet
731                  *               string T: T = T || Hash (Z || C)
732                  *--------------------------------------------------------------------*/
733 
734                 /* Hash Z||C */
735 #ifdef USE_MBEDTLS_CRYPTOCELL
736                 md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[hashFunc] );
737                 if (NULL == md_info)
738                 {
739                     return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
740                 }
741                 Error = mbedtls_md(md_info,
742                         T_TMP,
743                         ZSize + sizeof(uint32_t)/*counterSize*/,
744                         (unsigned char *)HashResultBuff);
745                 if (0 != Error)
746                 {
747                         return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
748                 }
749 #else
750                 Error = CC_Hash(hashFunc,
751                                 T_TMP,
752                                 ZSize + sizeof(uint32_t)/*counterSize*/,
753                                 HashResultBuff);
754 
755                 if (Error!=CC_OK)
756                         return Error;
757 #endif
758                 CC_PalMemCopy(Output_ptr, (uint8_t *)HashResultBuff, hLen);
759                 Output_ptr += hLen;
760         }
761 
762 /*---------------------------------------------------------------------*
763  * Step 4:  Output the leading L octets of T as the octet string mask. *
764  *---------------------------------------------------------------------*/
765         CC_PalMemCopy(Mask_ptr,(uint8_t *)T, L);
766 
767         return CC_OK;
768 }
769 #endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
770