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