1 /*
2  * Copyright (c) 2001-2022, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /*  Inculde Files */
8 #ifdef CC_IOT
9 #include "mbedtls/build_info.h"
10 #endif
11 
12 #ifndef USE_MBEDTLS_CRYPTOCELL
13 #include "cc_hash.h"
14 #endif
15 
16 #if !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C))
17 
18 #include "cc_pal_mem.h"
19 #include "cc_common_math.h"
20 #include "cc_rsa_local.h"
21 #include "cc_rsa_error.h"
22 #include "cc_hash_defs.h"
23 #include "cc_rnd_error.h"
24 #include "cc_rsa_prim.h"
25 #include "cc_general_defs.h"
26 
27 #ifdef CC_RSA_SIGN_USE_TEMP_SALT
28 #include "CRYS_RSA_PSS21_defines.h"
29 extern uint8_t SaltDB_T[NUM_OF_SETS_TEST_VECTORS][NUM_OF_TEST_VECTOR_IN_SET][CC_RSA_PSS_SALT_LENGTH];
30 extern uint16_t Global_Set_Index_T;
31 extern uint16_t Global_vector_Index_T;
32 #endif
33 
34 
35 #if !defined(_INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)
36 
37 /**********************************************************************************************************/
38 /**
39         Function Name: RsaPssVerify21
40         Date:   06-12-2004
41         Author: Ohad Shperling
42 
43     \brief RsaPssVerify21 implements EMSA-PSS-Verify algorithm
44    as defined in PKCS#1 v2.1 Sec 9.1.2
45 
46    @param[in] Context_ptr - Pointer to a valid context as
47                             given from the VerifyFinish function.
48 
49    The field HASH_Result inside the Context_ptr is initialized with the Hashed digested message.
50    The field HASH_Result_Size inside the Context_ptr is initialized with the Hash digested message size
51 
52    @return CCError_t - CC_OK, or error
53 
54 */
RsaPssVerify21(RSAPubContext_t * Context_ptr)55 CCError_t RsaPssVerify21(RSAPubContext_t *Context_ptr)
56 {
57         /**********Fitting to the spec******************************/
58         /* Context_ptr->MsgDigestCAL = mHash = Hash(M)
59      * &Context_ptr->KeyObj.PubObj.EBD[0] = pointer to EM = S^E mod N
60      * &Context_ptr->KeyObj.PubObj.EBDSize = pointer to EM size
61         */
62 
63 
64         CCError_t Error ;
65         uint8_t   *ED_ptr;
66         uint32_t  EDSizeInBytes;
67         uint32_t PubNNewSizeBytes,i;
68         uint8_t *maskedDB_ptr;
69 
70         uint32_t maskedDB_size;
71         uint32_t TempIndex ;
72         uint8_t *dbMask_ptr = Context_ptr->T_Buf;
73 #ifdef USE_MBEDTLS_CRYPTOCELL
74         const mbedtls_md_info_t *md_info=NULL;
75 #endif
76 
77         CCHashResultBuf_t H_Saved_buf;
78         /* Set the ED block pointer */
79 
80         /*Temporary - only for the size of N*/
81         CCRsaPubKey_t *PubKey_ptr = (CCRsaPubKey_t *)Context_ptr->PubUserKey.PublicKeyDbBuff;
82 
83         /* FUNCTION LOGIC */
84 
85         ED_ptr=(uint8_t*)&Context_ptr->EBD[0];/* = EM*/
86         EDSizeInBytes = Context_ptr->EBDSizeInBits/8;
87         if (Context_ptr->EBDSizeInBits % 8)
88                 EDSizeInBytes++;
89 
90         /*Round up the new bytes number - According to the Spec*/
91         PubNNewSizeBytes = (PubKey_ptr->nSizeInBits - 1)/8;
92 
93         if (((PubKey_ptr->nSizeInBits - 1) % 8) != 0) {/*Rounding Only in case that (PubNSizebits -1) is not divisble by 8 */
94                 PubNNewSizeBytes++;
95         } else {/*(PubNSizebits -1) is divisble by 8 hence ED_ptr has to be shortened by the first octet according to the spec*/
96                 ED_ptr += 1;
97                 EDSizeInBytes -= 1;
98         }
99 
100         /*
101          *  9.1.2 <3> Check restriction of PubNNewSizeBytes - already checked in Verify Init
102          *  9.1.2 <4> Check that the rightmost octet of EM have the hexadecimal value 0xbc
103          */
104         if (ED_ptr[EDSizeInBytes-1] != 0xbc)
105                 return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
106 
107         /*
108          *  9.1.2 <5> Define the H and the maskedDB
109          */
110         maskedDB_ptr = ED_ptr;
111         maskedDB_size = PubNNewSizeBytes - Context_ptr->HASH_Result_Size*sizeof(uint32_t) - 1 ;
112 
113         /*
114          *  9.1.2 <6> Check that the leftmost bits in the leftmost octet of EM have the value 0.
115          *     Note: In CC implementation only the left most bit must be checked, because the
116          *           modulus size is always a multiple of 8 bits.
117          */
118         if (maskedDB_ptr[0] & 0x80)
119                 return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
120 
121         /*need to save H because ED_ptr is to be used - Context_ptr->MsgDigestSRC = H;
122           i.e. COPIed hash size bytes directly before 0xbc byte (FIPS 186-4, 5.4)      */
123         CC_PalMemCopy((uint8_t *)H_Saved_buf, &ED_ptr[maskedDB_size], Context_ptr->HASH_Result_Size*4);
124 
125         /* Calculate the mask by MGF */
126         switch (Context_ptr->MGF_2use) {
127         case CC_PKCS1_MGF1:
128 
129                 Error = RsaOaepMGF1( (uint16_t)(Context_ptr->HASH_Result_Size*sizeof(uint32_t)), /*hashLen*/
130                                            (uint8_t *)H_Saved_buf,                                 /*mgfSeed = hash */
131                                            (uint16_t)(Context_ptr->HASH_Result_Size*sizeof(uint32_t)),/*seedLen*/
132                                            PubNNewSizeBytes - Context_ptr->HASH_Result_Size*sizeof(uint32_t) - 1, /*maskLen*/
133                                            dbMask_ptr,                                             /*mask out*/
134                                            Context_ptr->HashOperationMode,                         /*hashMode*/
135                                            (uint8_t *)Context_ptr->PrimeData.DataOut,              /*1-st tempBuff*/
136                                            (uint8_t *)Context_ptr->PrimeData.DataIn);              /*2-nd tempBuff*/
137                 if (Error != CC_OK) {
138                         return Error;
139                 }
140 
141                 break;
142 
143         /*Currently for PKCS1 Ver 2.1 only MGF1 is implemented*/
144         case CC_PKCS1_NO_MGF:
145         default:
146                 return CC_RSA_MGF_ILLEGAL_ARG_ERROR;
147         }
148 
149         /*
150          *  9.1.2 <8> Xor operation on length (PubNNewSizeBytes - Context_ptr->hLen - 1)
151          */
152 
153         for (i=0;i<maskedDB_size;i++) {
154                 dbMask_ptr[i] = dbMask_ptr[i] ^ maskedDB_ptr[i] ;
155         }
156 
157         /*
158          *  9.1.2 <9> Set the leftmost 8emLen - emBits bits of the leftmost octet in DB to zero
159          *     Note: In CC implementation only NS bit must be zeroed, because modulus size is
160          *           always a multiple of 8 bits.
161          */
162         dbMask_ptr[0] &= 0x7F;
163 
164         /*
165          *  9.1.2 <10>
166          */
167 
168         i=0;
169         while (dbMask_ptr[i] == 0) {
170                 i++;
171         }
172 
173         if (Context_ptr->SaltLen == CC_RSA_VERIFY_SALT_LENGTH_UNKNOWN) {
174 
175                 /* For security goals and preventing memory overflow
176                    check that the buffer parts are consistent */
177                 if (PubNNewSizeBytes < Context_ptr->HASH_Result_Size*sizeof(uint32_t) + 2 + i) {
178                         return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
179                 }
180                 /*Derive the salt length if not supplied */
181                 Context_ptr->SaltLen = (uint16_t)(PubNNewSizeBytes - Context_ptr->HASH_Result_Size*sizeof(uint32_t) - 2 - i);
182         } else {
183             /* Sanity check - verify that the given Saltlen equals the computed saltlen*/
184                 if (Context_ptr->SaltLen != (uint16_t)(PubNNewSizeBytes - Context_ptr->HASH_Result_Size*sizeof(uint32_t) - 2 - i))
185                 {
186                     return CC_RSA_ERROR_IN_DECRYPTED_BLOCK_PARSING;
187                 }
188                 TempIndex = PubNNewSizeBytes - Context_ptr->HASH_Result_Size*sizeof(uint32_t) - Context_ptr->SaltLen - 2;
189                 for (i = 0; i < TempIndex; i++) {
190                         if (dbMask_ptr[i] != 0)
191                                 return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
192                 }
193         }
194 
195         if (dbMask_ptr[i] != 0x01)
196                 return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
197 
198         /*
199          *  9.1.2 <11> Let salt be the last sLen octets in DB
200          *  9.1.2 <12> Let M' ==>
201          *   (0x) 00 00 00 00 00 00 00 00 || mHash || salt
202          *   Note: ED is used now as M' temp buffer
203          */
204         CC_PalMemSetZero(ED_ptr, CC_RSA_PSS_PAD1_LEN);/*CC_RSA_PSS_PAD1_LEN = 8*/
205 
206         /*copy the Hash output */
207         CC_PalMemCopy(&ED_ptr[CC_RSA_PSS_PAD1_LEN], (uint8_t *)Context_ptr->HASH_Result, Context_ptr->HASH_Result_Size*sizeof(uint32_t));
208         CC_PalMemCopy(&ED_ptr[CC_RSA_PSS_PAD1_LEN + Context_ptr->HASH_Result_Size*sizeof(uint32_t)],
209                         &dbMask_ptr[maskedDB_size - Context_ptr->SaltLen], Context_ptr->SaltLen);
210 
211         /*
212          *  9.1.2 <13> H' = Hash(M')
213          */
214 #ifdef USE_MBEDTLS_CRYPTOCELL
215         md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[Context_ptr->HashOperationMode] );
216         if (NULL == md_info)
217         {
218             return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
219         }
220         Error = mbedtls_md(md_info,
221                 ED_ptr,
222                 CC_RSA_PSS_PAD1_LEN + Context_ptr->HASH_Result_Size*sizeof(uint32_t) + Context_ptr->SaltLen,
223                 (unsigned char *)Context_ptr->HASH_Result);
224         if (Error != 0)
225         {
226             return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
227         }
228 #else
229         Error = CC_Hash(Context_ptr->HashOperationMode,
230                           ED_ptr,
231                           CC_RSA_PSS_PAD1_LEN + Context_ptr->HASH_Result_Size*sizeof(uint32_t) + Context_ptr->SaltLen,/*8+20+20*/
232                           Context_ptr->HASH_Result);
233 
234         if (Error != CC_OK) {
235                 return Error;
236         }
237 #endif
238         if (CC_PalMemCmp((uint8_t *)Context_ptr->HASH_Result, (uint8_t *)H_Saved_buf, Context_ptr->HASH_Result_Size*sizeof(uint32_t))) {
239                 return CC_RSA_ERROR_PSS_INCONSISTENT_VERIFY;
240         } else {
241                 return CC_OK;
242         }
243 }
244 
245 #endif /*!defined(_INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_VERIFY_SUPPORT)*/
246 
247 
248 
249 #if !defined(_INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_SIGN_SUPPORT)
250 #ifndef _INTERNAL_CC_NO_RSA_SIGN_SUPPORT
251 /* -------------------------------------------------------------
252  *  Function Name: RsaPssSign21
253  *  Date:   06-12-2004
254  *  Author: Ohad Shperling
255  *
256  *  Inputs:
257  *  Outputs:
258  *
259  *  Algorithm: According to PKCS1 v.2.1
260  *
261  *  Update History:
262  *  Date:       Description:
263  *
264  * ----------------------------------------------------------- */
265 
RsaPssSign21(CCRndContext_t * rndContext_ptr,RSAPrivContext_t * Context_ptr,uint8_t * Output_ptr)266 CCError_t RsaPssSign21(
267                                CCRndContext_t *rndContext_ptr, /*! random context */
268                                RSAPrivContext_t *Context_ptr,
269                                uint8_t  *Output_ptr)
270 {
271 
272 #ifdef CC_RSA_SIGN_USE_TEMP_SALT
273         /*only for debug of signing*/
274         /*Using a known Salt for debug*/
275         uint8_t *Salt = SaltDB_T[Global_Set_Index_T][Global_vector_Index_T];
276 #else
277         /*In operational mode Salt is a random number*/
278         uint8_t *Salt = Output_ptr;/*This stack memory saving is ok because Output_ptr is used only in the Primitive operation*/
279 #endif
280 #ifdef USE_MBEDTLS_CRYPTOCELL
281                 const mbedtls_md_info_t *md_info=NULL;
282 #endif
283         /* The return error identifier */
284         CCError_t Error = CC_OK;
285         uint32_t i;
286         uint32_t TempIndex;
287 
288         void   *rndState_ptr;
289         CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
290 
291         /*Parameter for the actual size of the modulus N in bits*/
292         uint32_t PrvNSizebits;
293 
294         /*Parameter for the new size of the modulus N in bytes according to PKCS1 Ver 2.1*/
295         uint32_t PrvNNewSizeBytes;/*rounded number of Bytes for padding2 length*/
296         uint32_t Index4PSLength;
297 
298         uint8_t *EMPadOutputBuffer;
299         uint8_t *MaskOutput_ptr = Context_ptr->T_Buf;/*for stack space saving*/
300 
301         CCRsaPrivKey_t *PrivKey_ptr = (CCRsaPrivKey_t *)Context_ptr->PrivUserKey.PrivateKeyDbBuff;
302         uint32_t hashResultSize; /*HASH size in bytes*/
303 
304 
305         /* FUNCTION LOGIC */
306 
307         /* check parameters */
308         if (rndContext_ptr == NULL)
309                 return CC_RND_CONTEXT_PTR_INVALID_ERROR;
310 
311         rndState_ptr = rndContext_ptr->rndState;
312         RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
313 
314         if (RndGenerateVectFunc == NULL)
315                 return CC_RND_GEN_VECTOR_FUNC_ERROR;
316 
317         /* .................. initializing local variables ................... */
318         /* ------------------------------------------------------------------- */
319 
320         EMPadOutputBuffer = (uint8_t*) Context_ptr->EBD;
321         hashResultSize = Context_ptr->HASH_Result_Size*sizeof(uint32_t);
322 
323         /*
324          *  9.1.1 <1> checking length restriction of the message M - done in the Update phase
325          *  9.1.1 <2> Hash operation - done in the Update phase
326          */
327 
328         /*
329          *  Finding Actual size in bits and new size of Bytes of the modulus N
330          *  This value is already calculated in  Context_ptr->KeyObj.PrvCRTObj.nSizeInBits
331          *  or in  Context_ptr->KeyObj.PrvPAIRObj.nSizeInBits
332          */
333 
334         /* Reset the working buffer - RL - check */
335         CC_PalMemSet(EMPadOutputBuffer, 0x00, CC_RSA_MAXIMUM_MOD_BUFFER_SIZE_IN_WORDS*sizeof(uint32_t));
336 
337         /*Round up the new bytes number*/
338         PrvNNewSizeBytes = (PrivKey_ptr->nSizeInBits -1)/8;
339         PrvNSizebits = PrivKey_ptr->nSizeInBits;
340 
341         if (((PrvNSizebits -1) % 8) != 0)
342                 PrvNNewSizeBytes++;
343         /*rounding */
344 
345         /*
346          *  9.1.1 <3> Check restriction of PrvNNewSizeBytes - already checked in Sign Init
347          *  9.1.1 <5> Generating M' ==> using the output buffer as a container
348          *  EMPadOutputBuffer = (0x) 00 00 00 00 00 00 00 00 || mHash || salt
349          */
350 
351         CC_PalMemSet(EMPadOutputBuffer, 0x00, CC_RSA_PSS_PAD1_LEN);/*CC_RSA_PSS_PAD1_LEN = 8*/
352 
353         /*copy the Hash output */
354         CC_PalMemCopy(&EMPadOutputBuffer[CC_RSA_PSS_PAD1_LEN], (uint8_t*)Context_ptr->HASH_Result, hashResultSize);
355 
356         /*
357          *  9.1.1 <4> Generating a random salt ==> using the output buffer as a container
358          */
359 #ifndef CC_RSA_SIGN_USE_TEMP_SALT /*If not using a known salt for Debug then generate random*/
360         Error = RndGenerateVectFunc(rndState_ptr, (unsigned char *)Salt, (size_t)Context_ptr->SaltLen);
361         if (Error != CC_OK) {
362                 return Error;
363         }
364 #endif
365 
366         CC_PalMemCopy(&EMPadOutputBuffer[CC_RSA_PSS_PAD1_LEN + hashResultSize], Salt, Context_ptr->SaltLen);
367 #ifdef USE_MBEDTLS_CRYPTOCELL
368         md_info = mbedtls_md_info_from_string( HashAlgMode2mbedtlsString[Context_ptr->HashOperationMode] );
369         if (NULL == md_info)
370         {
371             return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
372         }
373         Error = mbedtls_md(md_info,
374                 EMPadOutputBuffer,
375                 CC_RSA_PSS_PAD1_LEN + hashResultSize + Context_ptr->SaltLen,/*8+hLen+20*/
376                 (unsigned char *)Context_ptr->HASH_Result);
377 
378         if (Error != 0)
379         {
380             return CC_RSA_HASH_ILLEGAL_OPERATION_MODE_ERROR;
381         }
382 #else
383         Error = CC_Hash(Context_ptr->HashOperationMode,
384                           EMPadOutputBuffer,
385                           CC_RSA_PSS_PAD1_LEN + hashResultSize + Context_ptr->SaltLen,/*8+hLen+20*/
386                           Context_ptr->HASH_Result);
387 
388         if (Error != CC_OK) {
389                 return Error;
390         }
391 #endif
392         /*
393          *  9.1.1 <7+8> Generate an octet string of zeros of size emLen-sLen-hLen-2 ==> use the output buffer as a container
394          *              DB = PS || 0x01 || salt
395          */
396 
397         Index4PSLength = PrvNNewSizeBytes - Context_ptr->SaltLen - hashResultSize - 2;
398 
399         CC_PalMemSet(EMPadOutputBuffer, 0x00, Index4PSLength);
400         EMPadOutputBuffer[Index4PSLength] = 0x01;
401         CC_PalMemCopy(&(EMPadOutputBuffer[Index4PSLength+1]), Salt, Context_ptr->SaltLen);
402 
403         /*
404          *  9.1.1 <9> MGF operation
405          */
406 
407         switch (Context_ptr->MGF_2use) {
408         case CC_PKCS1_MGF1:
409 
410                 Error = RsaOaepMGF1( (uint16_t)hashResultSize, /* hashLen */
411                                            (uint8_t *)Context_ptr->HASH_Result,         /* mgfSeed */
412                                            (uint16_t)hashResultSize, /* seedLen */
413                                            PrvNNewSizeBytes - hashResultSize - 1, /* maskLen */
414                                            MaskOutput_ptr,                              /* mask */
415                                            Context_ptr->HashOperationMode,              /* hashMode */
416                                            (uint8_t *)Context_ptr->PrimeData.DataOut,   /* temp1 */
417                                            (uint8_t *)Context_ptr->PrimeData.DataIn);   /* temp2 */
418                 if (Error != CC_OK) {
419                         return Error;
420                 }
421 
422                 break;
423 
424         /* Currently for PKCS1 Ver 2.1 only MGF1 is implemented */
425         case CC_PKCS1_NO_MGF:
426 
427         default:
428 
429                 return CC_RSA_MGF_ILLEGAL_ARG_ERROR;
430 
431         }/* end of MGF type switch case */
432 
433 
434         /*
435          *  9.1.1 <10> Xor operation on length (PrvNNewSizeBytes - Context_ptr->hLen - 1)
436          */
437 
438         TempIndex = PrvNNewSizeBytes - hashResultSize - 1;
439         for (i = 0; i < TempIndex; i++) {
440                 EMPadOutputBuffer[i] = EMPadOutputBuffer[i] ^ MaskOutput_ptr[i];
441         }
442 
443 
444         /*
445          *   9.1.1 <11> Set the leftmost 8*emLen-emBits bits of the leftmost octet in maskedDB to zero
446          *      Because the RSA modulus in CC always is a multiple of 8, only one (left most) bit
447          *              need to be zeroed.
448          */
449          EMPadOutputBuffer[0] &= 0x7F;
450 
451         /*
452          *  ? 9.1.1 <12> Let EM = maskedDB || H || 0xbc
453          *      Note: maskedDB is already generated from the Xor operation.
454          */
455         CC_PalMemCopy(&(EMPadOutputBuffer[PrvNNewSizeBytes - hashResultSize - 1]),
456                          (uint8_t *)Context_ptr->HASH_Result, hashResultSize);
457 
458         EMPadOutputBuffer[PrvNNewSizeBytes - 1] = 0xbc;
459 
460         /*
461          *  FINISH 9.1.1
462          *
463          *  8.1.1 <2.b>
464          *  Apply the RSASP1 signature primitive to the RSA private key K and the message
465          *  representative m to produce an integer signature representative s
466          *
467          */
468 
469         /* ...  execute RSA encrypt using RSA_PRIM_Decrypt for exponentiation ... */
470         /* ---------------------------------------------------------------------- */
471 
472         Error = CC_RsaPrimDecrypt(&Context_ptr->PrivUserKey,
473                                       &Context_ptr->PrimeData,
474                                       EMPadOutputBuffer,
475                                       (uint16_t)PrvNNewSizeBytes,
476                                       Output_ptr);
477 
478         return Error;
479 
480 }
481 
482 #endif /*!defined(_INTERNAL_CC_NO_RSA_SCHEME_21_SUPPORT) && !defined(_INTERNAL_CC_NO_RSA_SIGN_SUPPORT)*/
483 
484 
CC_RSA_PSS21_UTIL_foo(void)485 void CC_RSA_PSS21_UTIL_foo(void) {}
486 #endif //_INTERNAL_CC_NO_RSA_SIGN_SUPPORT
487 #endif /* !defined(CC_IOT) || ( defined(CC_IOT) && defined(MBEDTLS_RSA_C)) */
488