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