1 /*
2  * Copyright (c) 2001-2019, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /************* Include Files ****************/
8 
9 #include "cc_pal_mem.h"
10 #include "cc_common.h"
11 #include "cc_common_math.h"
12 #include "cc_rnd_common.h"
13 #include "cc_rnd_error.h"
14 #include "cc_rnd_local.h"
15 #include "cc_dh_error.h"
16 #include "cc_dh.h"
17 #include "cc_dh_kg.h"
18 #include "cc_rsa_build.h"
19 #include "cc_rsa_prim.h"
20 #include "rsa.h"
21 #include "rsa_public.h"
22 #include "rsa_private.h"
23 #include "cc_fips_defs.h"
24 
25 
26 /************************ Defines *******************************/
27 
28 /************************ Enums *********************************/
29 
30 /************************ macros ********************************/
31 
32 
33 /************************ global data ***********************************/
34 
35 /************************ Private Functions ******************************/
36 /* This function translates the DH hash modes into KDF hash modes */
MakeKDFHashMode(CCDhHashOpMode_t hashMode)37 static CCKdfHashOpMode_t MakeKDFHashMode(CCDhHashOpMode_t hashMode)
38 {
39 
40         CCKdfHashOpMode_t outMode;
41 
42         switch (hashMode) {
43         case CC_DH_HASH_SHA1_mode:
44                 outMode = CC_KDF_HASH_SHA1_mode;
45                 break;
46         case CC_DH_HASH_SHA224_mode:
47                 outMode = CC_KDF_HASH_SHA224_mode;
48                 break;
49         case CC_DH_HASH_SHA256_mode:
50                 outMode = CC_KDF_HASH_SHA256_mode;
51                 break;
52         case CC_DH_HASH_SHA384_mode:
53                 outMode = CC_KDF_HASH_SHA384_mode;
54                 break;
55         case CC_DH_HASH_SHA512_mode:
56                 outMode = CC_KDF_HASH_SHA512_mode;
57                 break;
58         default:
59                 outMode = CC_KDF_HASH_OpModeLast;
60         }
61 
62         return outMode;
63 }
64 
65 /* This function translates the DH deriveFunc enum to KDF derive func enum */
MakeKDFDeriveFuncMode(CCDhDerivationFuncMode_t deriveFunc)66 static CCKdfDerivFuncMode_t MakeKDFDeriveFuncMode(CCDhDerivationFuncMode_t deriveFunc)
67 {
68 
69         CCKdfDerivFuncMode_t outDeriveFunc;
70 
71         switch (deriveFunc) {
72         case CC_DH_ASN1_Der_mode:
73                 outDeriveFunc = CC_KDF_ASN1_DerivMode;
74                 break;
75         case CC_DH_X963_DerMode:
76                 outDeriveFunc = CC_KDF_ConcatDerivMode;
77                 break;
78         default:
79                 outDeriveFunc = CC_KDF_DerivFuncModeLast;
80         }
81 
82         return outDeriveFunc;
83 }
84 /************************ Public Functions ******************************/
85 
86 
CC_DhGeneratePubPrv(CCRndContext_t * rndContext_ptr,uint8_t * Generator_ptr,size_t GeneratorSize,uint8_t * Prime_ptr,size_t PrimeSize,uint16_t L,uint8_t * Q_ptr,size_t QSize,CCDhOpMode_t DH_mode,CCDhUserPubKey_t * tmpPubKey_ptr,CCDhPrimeData_t * tmpPrimeData_ptr,uint8_t * ClientPrvKey_ptr,size_t * ClientPrvKeySize_ptr,uint8_t * ClientPub1_ptr,size_t * ClientPubSize_ptr)87 CEXPORT_C CCError_t CC_DhGeneratePubPrv(
88                                            CCRndContext_t *rndContext_ptr,
89                                            uint8_t *Generator_ptr,              /*generator*/
90                                            size_t GeneratorSize,
91                                            uint8_t *Prime_ptr,                  /*modulus*/
92                                            size_t PrimeSize,
93                                            uint16_t L,         /*Exact length of Private key in bits*/
94                                            uint8_t *Q_ptr,                      /*order/in*/
95                                            size_t QSize,
96                                            CCDhOpMode_t DH_mode,            /*in*/
97                                            CCDhUserPubKey_t *tmpPubKey_ptr,  /*temp buff*/
98                                            CCDhPrimeData_t  *tmpPrimeData_ptr, /*temp buff*/
99                                            uint8_t *ClientPrvKey_ptr,           /*out*/
100                                            size_t  *ClientPrvKeySize_ptr,      /*in/out*/
101                                            uint8_t *ClientPub1_ptr,             /*out*/
102                                            size_t  *ClientPubSize_ptr)         /*in/out*/
103 
104 {
105         /* FUNCTION DECLARATIONS */
106 
107         /* The return error identifier */
108         CCError_t Error = CC_OK;
109 
110         /* temporary byte shift masks */
111         uint8_t tmpByte, mask, mask1, shift;
112 
113         /* the vector 2^(L-1) size*/
114         uint16_t tmpSize;
115 
116         /* the comparing value, returned from the vectors compare */
117         CCCommonCmpCounter_t comp;
118 
119         CCRndState_t   *rndState_ptr;
120         CCRndGenerateVectWorkFunc_t RndGenerateVectFunc;
121 
122     CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
123 
124 
125         /* ............... checking the parameters validity ................... */
126         /* -------------------------------------------------------------------- */
127 
128         /* check parameters */
129         if (rndContext_ptr == NULL)
130                 return CC_RND_CONTEXT_PTR_INVALID_ERROR;
131         if (rndContext_ptr->rndGenerateVectFunc == NULL)
132                 return CC_RND_GEN_VECTOR_FUNC_ERROR;
133 
134         rndState_ptr = (CCRndState_t *)(rndContext_ptr->rndState);
135         RndGenerateVectFunc = rndContext_ptr->rndGenerateVectFunc;
136 
137         /* if an argument pointer is NULL return an error */
138         if (Generator_ptr == NULL || Prime_ptr == NULL ||
139             ClientPrvKey_ptr == NULL || ClientPub1_ptr == NULL ||
140             ClientPrvKeySize_ptr == NULL || ClientPubSize_ptr == NULL ||
141             tmpPubKey_ptr == NULL || tmpPrimeData_ptr == NULL)
142                 return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
143 
144         /* check DH mode */
145         if (DH_mode > CC_DH_NumOfModes)
146                 return CC_DH_INVALID_ARGUMENT_OPERATION_MODE_ERROR;
147 
148         /* preliminary check of sizes */
149         if (PrimeSize > CC_DH_MAX_MOD_SIZE_IN_BYTES || PrimeSize == 0)
150                 return CC_DH_INVALID_MODULUS_SIZE_ERROR;
151 
152         if (GeneratorSize == 0 || GeneratorSize > PrimeSize)
153                 return CC_DH_INVALID_ARGUMENT_SIZE_ERROR;
154 
155         if (*ClientPubSize_ptr < PrimeSize)
156                 return CC_DH_INVALID_PUBLIC_KEY_SIZE_ERROR;
157 
158         if (*ClientPrvKeySize_ptr < PrimeSize)
159                 return CC_DH_SECRET_KEY_SIZE_OUTPUT_ERROR;
160 
161 
162         /* Check the the generator according to DH mode */
163     if (DH_mode == CC_DH_PKCS3_mode)
164             tmpByte = 0; /* for checking PKCS3 part 6.  0 < g < p */
165     else  /* CC_DH_ANSI_X942_mode */
166         tmpByte = 1; /* for checking ANSI_X942 part 7.2.  1 < g < p-1 */
167 
168         comp = CC_CommonCmpMsbUnsignedCounters( Generator_ptr,
169                                                    GeneratorSize,
170                                                    &tmpByte, 1);
171 
172         if (comp != CC_COMMON_CmpCounter1GreaterThenCounter2)
173                 return CC_DH_ARGUMENT_GENERATOR_SMALLER_THAN_ZERO_ERROR;
174 
175         /*Compare the generator and the Prime: requested that g < P-1 */
176         Prime_ptr[PrimeSize-1] -= tmpByte; /* temporary p = p-1 */
177         comp = CC_CommonCmpMsbUnsignedCounters( Generator_ptr, GeneratorSize,
178                                                    Prime_ptr, PrimeSize );
179 
180         if (comp != CC_COMMON_CmpCounter2GreaterThenCounter1)
181                 return CC_DH_ARGUMENT_PRIME_SMALLER_THAN_GENERATOR_ERROR;
182 
183         /* repair P */
184         Prime_ptr[PrimeSize-1] += tmpByte;
185 
186         /*--------------------------------------------------------------------------------*/
187         /*         DH public-private keys generation                                      */
188         /*--------------------------------------------------------------------------------*/
189 
190         /* temporary set prime modulus into temp buffer in little endianness */
191         // RL Endianness
192         CC_CommonReverseMemcpy( (uint8_t*)tmpPrimeData_ptr->DataIn , Prime_ptr , PrimeSize );
193 
194         /* get actual size of prime in bits: min() used to prevent warnings */
195         tmpSize = CC_MIN( PrimeSize*8,
196                        (uint16_t)CC_CommonGetBytesCounterEffectiveSizeInBits(
197                                            (uint8_t*)tmpPrimeData_ptr->DataIn, PrimeSize) );
198 
199         /* correction of Prime_ptr pointer and Size for removing of not significant zero-bytes */
200         if (PrimeSize - CALC_FULL_BYTES(tmpSize) > 0) {
201                 Prime_ptr += PrimeSize - CALC_FULL_BYTES(tmpSize);
202                 PrimeSize = CALC_FULL_BYTES(tmpSize);
203         }
204 
205         switch (DH_mode) {
206         case CC_DH_PKCS3_mode:
207                 /* ----------------------------------------------------------- *
208             PKCS#3:  set x private random value according to following:
209                                    1) If L = 0: set    0 < x < P-1;
210                                    2) If L > 0: set  2^(L-1) <= x < 2^L ,
211                                            where 2^(L-1) <= P.
212                   ----------------------------------------------------------- */
213                 if (L == 0) {
214                         /* Option 1: L is not provided - check the minimum size of the private key buffer */
215                         if (*ClientPrvKeySize_ptr < PrimeSize) {
216                                 Error = CC_DH_ARGUMENT_PRV_SIZE_ERROR;
217                                 goto End1;
218                         }
219 
220                         /* random generation in range:  0 < x < P-1  (in little endian */
221                         Error = CC_RndGenerateVectorInRange( rndContext_ptr,
222                                                                 tmpSize /*rndSizeInBits*/,
223                                                                 (uint8_t*)tmpPrimeData_ptr->DataIn/*maxVect*/,
224                                                                 (uint8_t*)tmpPrimeData_ptr->DataOut/*out*/ );
225                         if (Error != CC_OK)
226                                 goto End;
227 
228                         /* reverse privKey to big endianness */
229                         CC_CommonReverseMemcpy( ClientPrvKey_ptr , (uint8_t*)tmpPrimeData_ptr->DataOut , PrimeSize );
230 
231                         /* private key size in bytes */
232                         *ClientPrvKeySize_ptr = PrimeSize;
233                 }
234                 else {  /* Option 2:  L > 0 and bit length of privKey must be exactly L bit */
235                         /* check L and the minimum size of the private key buffer */
236                         if (L > tmpSize) {
237                                 Error = CC_DH_INVALID_L_ARGUMENT_ERROR;
238                                 goto End1;
239                         }
240                         if ((*ClientPrvKeySize_ptr)*8 < L) {
241                                 Error = CC_DH_ARGUMENT_PRV_SIZE_ERROR;
242                                 goto End1;
243                         }
244 
245                         /* actual private key size in bytes and shift value */
246                         *ClientPrvKeySize_ptr = CALC_FULL_BYTES(L);
247                         if (*ClientPrvKeySize_ptr > CC_DH_MAX_MOD_SIZE_IN_BYTES) {
248                                 Error = CC_DH_ARGUMENT_PRV_SIZE_ERROR;
249                                 goto End1;
250             }
251                         shift = ((8 - (L & 7)) & 7);
252 
253                         /* if L = modulus size, then generate random x with exact bit-size = L
254                            and value in range:  2^(L-1) < x < P */
255                         if (L == tmpSize) {
256                                 mask   = 0x7F >> shift;
257                                 mask1  = 0x80 >> shift;
258 
259                                 /* set temporary MSBit of modulus = 0 for generation random in range without MSbit */
260                                 ((uint8_t*)tmpPrimeData_ptr->DataIn)[*ClientPrvKeySize_ptr - 1] &= mask;
261 
262                                 /* generate random in range */
263                                 Error = CC_RndGenerateVectorInRange(rndContext_ptr,
264                                                                       tmpSize /*rndSizeInBits*/,
265                                                                       (uint8_t*)tmpPrimeData_ptr->DataIn/*maxVect*/,
266                                                                       (uint8_t*)tmpPrimeData_ptr->DataOut/*out*/ );
267 
268                                 if (Error != CC_OK)
269                                         goto End;
270 
271                                 /* set MSBit of random to 1 */
272                                 ((uint8_t*)tmpPrimeData_ptr->DataIn)[*ClientPrvKeySize_ptr - 1] |= mask1;
273 
274                                 /* reverse privKey to big endianness */
275                                 CC_CommonReverseMemcpy( ClientPrvKey_ptr , (uint8_t*)tmpPrimeData_ptr->DataOut , *ClientPrvKeySize_ptr );
276                         }
277                         /* if L < modulus size, then generate random x of size L bits */
278                         else {
279                                 /* random generation */
280                                 Error = RndGenerateVectFunc((void *)rndState_ptr, (unsigned char *)ClientPrvKey_ptr, *ClientPrvKeySize_ptr );
281 
282                                 if (Error != CC_OK)
283                                         goto End;
284 
285                                 /* set two appropriate high bits of privKey to 00..1 to met the requirement 2^(L-1) <= x < 2^L */
286                                 if ((L & 7) > 0) {
287                                         mask  = 0xFF >> shift;
288                                         mask1 = 0x80 >> shift;
289                                         ClientPrvKey_ptr[0] = (ClientPrvKey_ptr[0] & mask) | mask1;
290                                 }
291                                 /* if( (L & 7) == 0 ) */
292                                 else {
293                                         ClientPrvKey_ptr[0] |= 0x80;
294                                 }
295                         }
296                 }
297 
298                 break;
299 
300         case CC_DH_ANSI_X942_mode:
301                 /* ----------------------------------------------------------- *
302                                               ANS X9.42:
303                                  1<= X <= q-1 or    1< X <= q-1
304                  --------------------------------------------------------------*/
305 
306                 /* check order */
307                 if (Q_ptr == NULL) {
308                         Error = CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
309                         goto End1;
310                 }
311 
312                 if (QSize == 0 || QSize > PrimeSize) {
313                         Error = CC_DH_INVALID_ORDER_SIZE_ERROR;
314                         goto End1;
315                 }
316 
317                 /* check client private key buffer size */
318                 if (*ClientPrvKeySize_ptr < QSize) {
319                         Error = CC_DH_ARGUMENT_PRV_SIZE_ERROR;
320                         goto End1;
321                 }
322 
323                 /* set order Q into temp buffer in little endianness */
324                 CC_CommonReverseMemcpy( (uint8_t*)tmpPrimeData_ptr->DataIn, Q_ptr, QSize );
325 
326                 /* get actual size in bits */
327                 tmpSize = (uint16_t)CC_CommonGetBytesCounterEffectiveSizeInBits(
328                                                                                     (uint8_t*)tmpPrimeData_ptr->DataIn,
329                                                                                     QSize );
330                 /* private key size in bytes */
331                 *ClientPrvKeySize_ptr = CALC_FULL_BYTES(tmpSize);
332 
333                 /* random in range:  1 < x < Q  (little endianness) */
334                 Error = CC_RndGenerateVectorInRange( rndContext_ptr,
335                                                         tmpSize /*rndSizeInBits*/,
336                                                         (uint8_t*)tmpPrimeData_ptr->DataIn/*maxVect*/,
337                                                         (uint8_t*)tmpPrimeData_ptr->DataOut/*out*/);
338                 if (Error != CC_OK)
339                         goto End;
340 
341                 /* reverse privKey to big endianness */
342                 CC_CommonReverseMemcpy(ClientPrvKey_ptr, (uint8_t*)tmpPrimeData_ptr->DataOut, *ClientPrvKeySize_ptr);
343 
344                 break;
345 
346         default:
347                 Error = CC_DH_INVALID_ARGUMENT_OPERATION_MODE_ERROR;
348                 goto End1;
349 
350         }
351 
352         /* ----------------------------------------------------------- */
353         /*           Create the public key                             */
354         /* ----------------------------------------------------------- */
355 
356         /* Build the RSA PublKey data structure for the Exp operation, using RSA_Encrypt primitive */
357         Error = CC_RsaPubKeyBuild(
358                                      tmpPubKey_ptr,
359                                      ClientPrvKey_ptr,
360                                      *ClientPrvKeySize_ptr,
361                                      Prime_ptr,
362                                      PrimeSize );
363         /* check error */
364         if (Error != CC_OK) {
365                 goto End;
366         }
367 
368         /*Call the exponent operation to calculate the ClientPub1 = Generator^privKey mod Prime */
369         Error = CC_RsaPrimEncrypt(
370                                      tmpPubKey_ptr,
371                                      tmpPrimeData_ptr,
372                                      Generator_ptr,
373                                      GeneratorSize,
374                                      ClientPub1_ptr );
375         if (Error != CC_OK) {
376                 goto End;
377         }
378 
379         *ClientPubSize_ptr = PrimeSize;
380 
381 End:
382 
383     if (Error != CC_OK) {
384         CC_PalMemSetZero( ClientPrvKey_ptr, *ClientPrvKeySize_ptr);
385         *ClientPrvKeySize_ptr = 0;
386     }
387 End1:
388         /* delete secure sensitive data */
389         CC_PalMemSetZero( tmpPubKey_ptr, sizeof(CCDhUserPubKey_t) );
390         CC_PalMemSetZero( tmpPrimeData_ptr, sizeof(CCDhPrimeData_t) );
391 
392         return Error;
393 
394 }/* END OF CC_DhGeneratePubPrv function */
395 
396 
CC_DhGetSecretKey(uint8_t * ClientPrvKey_ptr,size_t ClientPrvKeySize,uint8_t * ServerPubKey_ptr,size_t ServerPubKeySize,uint8_t * Prime_ptr,size_t PrimeSize,CCDhUserPubKey_t * tmpPubKey_ptr,CCDhPrimeData_t * tmpPrimeData_ptr,uint8_t * SecretKey_ptr,size_t * SecretKeySize_ptr)397 CEXPORT_C CCError_t CC_DhGetSecretKey(
398                                           uint8_t *ClientPrvKey_ptr,
399                                           size_t ClientPrvKeySize,
400                                           uint8_t *ServerPubKey_ptr,
401                                           size_t ServerPubKeySize,
402                                           uint8_t *Prime_ptr,
403                                           size_t PrimeSize,
404                                           CCDhUserPubKey_t *tmpPubKey_ptr,
405                                           CCDhPrimeData_t  *tmpPrimeData_ptr,
406                                           uint8_t *SecretKey_ptr,
407                                           size_t *SecretKeySize_ptr)
408 {
409         /* FUNCTION DECLARATIONS */
410 
411         /* The return error identifier */
412         CCError_t Error = CC_OK;
413 
414         CCCommonCmpCounter_t cmpResult;
415         uint8_t one = 1;
416 
417     CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
418 
419 
420         /* ............... checking the parameters validity ................... */
421         /* -------------------------------------------------------------------- */
422 
423         /* if an argument pointer is NULL return an error */
424         if (ClientPrvKey_ptr == NULL || ServerPubKey_ptr == NULL ||
425             Prime_ptr == NULL || tmpPubKey_ptr == NULL ||
426             tmpPrimeData_ptr == NULL || SecretKey_ptr == NULL || SecretKeySize_ptr == NULL)
427 
428                 return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
429 
430         /*If an argument buffer size is zero return an error*/
431         if (PrimeSize == 0 || PrimeSize > CC_DH_MAX_MOD_SIZE_IN_BYTES ||
432             ClientPrvKeySize == 0 || ClientPrvKeySize > PrimeSize ||
433             ServerPubKeySize == 0 || ServerPubKeySize > PrimeSize ||
434             *SecretKeySize_ptr == 0 || *SecretKeySize_ptr < PrimeSize)
435                 return CC_DH_INVALID_ARGUMENT_SIZE_ERROR;
436 
437         /* 1. verifying that the private exponent is less than modulus, else subtract the modulus */
438         cmpResult = CC_CommonCmpMsbUnsignedCounters( ClientPrvKey_ptr, ClientPrvKeySize,
439                                                         Prime_ptr, PrimeSize );
440 
441         if (cmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
442                 /* subtract modulus prime from private key and set result in temp buffer */
443                 CC_CommonSubtractMSBUint8Arrays(ClientPrvKey_ptr, ClientPrvKeySize, Prime_ptr, PrimeSize,
444                                                    (uint8_t*)tmpPrimeData_ptr->DataIn);
445 
446                 /* build the Data for the Exp operation.
447                   Note: the user private key is set into public key structure */
448                 Error = CC_RsaPubKeyBuild(
449                                              tmpPubKey_ptr,
450                                              (uint8_t*)tmpPrimeData_ptr->DataIn,
451                                              ClientPrvKeySize,
452                                              Prime_ptr,
453                                              PrimeSize);
454         } else {
455                 /* build the Data for the Exp operation */
456                 Error = CC_RsaPubKeyBuild(
457                                              tmpPubKey_ptr,
458                                              ClientPrvKey_ptr,
459                                              ClientPrvKeySize,
460                                              Prime_ptr,
461                                              PrimeSize);
462         }
463 
464         if (Error != CC_OK)
465                 goto End;
466 
467         /* 3. create: Secret_key (or shared secret value) = Server_public_key *
468         *  ^ Prv mod Prime                                                    */
469         Error = CC_RsaPrimEncrypt(
470                                      tmpPubKey_ptr, /* Note: this is the private key */
471                                      tmpPrimeData_ptr,
472                                      ServerPubKey_ptr,
473                                      ServerPubKeySize,
474                                      SecretKey_ptr);
475 
476         if (Error != CC_OK)
477                 goto End;
478 
479         /* Secret key (shared secret value) size in bytes, including leading  *
480         *  zeroes                                                             */
481         *SecretKeySize_ptr = PrimeSize;
482 
483         /* Note: X9.42 7.5.1 requires that shared secret value != 1 */
484         cmpResult = CC_CommonCmpMsbUnsignedCounters(
485                                                 &one, 1/*size*/,
486                                                 SecretKey_ptr, PrimeSize);
487 
488         if (cmpResult != CC_COMMON_CmpCounter2GreaterThenCounter1) {
489                 Error = CC_DH_ARGUMENT_BUFFER_SIZE_ERROR;
490                 goto End;
491         }
492 
493 End:
494         /* delete secure sensitive data */
495         CC_PalMemSetZero(tmpPubKey_ptr, sizeof(CCDhUserPubKey_t));
496         CC_PalMemSetZero(tmpPrimeData_ptr, sizeof(CCDhPrimeData_t));
497 
498         return Error;
499 }  /* END of CC_DhGetSecretKey function */
500 
501 
502 
CC_DhX942GetSecretData(uint8_t * ClientPrvKey_ptr,size_t ClientPrvKeySize,uint8_t * ServerPubKey_ptr,size_t ServerPubKeySize,uint8_t * Prime_ptr,size_t PrimeSize,CCDhOtherInfo_t * otherInfo_ptr,CCDhHashOpMode_t hashMode,CCDhDerivationFuncMode_t DerivFunc_mode,CCDhTemp_t * tmpBuff_ptr,uint8_t * SecretKeyingData_ptr,size_t SecretKeyingDataSize)503 CEXPORT_C CCError_t CC_DhX942GetSecretData(
504                                                 uint8_t                  *ClientPrvKey_ptr,
505                                                 size_t                  ClientPrvKeySize,
506                                                 uint8_t                  *ServerPubKey_ptr,
507                                                 size_t                  ServerPubKeySize,
508                                                 uint8_t                  *Prime_ptr,
509                                                 size_t                  PrimeSize,
510                                                 CCDhOtherInfo_t      *otherInfo_ptr,
511                                                 CCDhHashOpMode_t     hashMode,
512                                                 CCDhDerivationFuncMode_t DerivFunc_mode,
513                                                 CCDhTemp_t           *tmpBuff_ptr,
514                                                 uint8_t                  *SecretKeyingData_ptr,
515                                                 size_t                   SecretKeyingDataSize )
516 {
517         /* FUNCTION DECLARATIONS */
518 
519         /* The return error identifier */
520         CCError_t Error = CC_OK;
521 
522         size_t  SecretKeySize = PrimeSize;
523 
524     CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
525 
526         /* check pointers */
527         if (tmpBuff_ptr == NULL || SecretKeyingData_ptr == NULL)
528                 return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
529 
530         /*check that the size of derived secret key is not NULL  */
531         if (SecretKeyingDataSize == 0)
532                 return CC_DH_SECRET_KEYING_DATA_SIZE_ILLEGAL_ERROR;
533 
534         /*check that the keying data size is not too large  */
535         if (SecretKeyingDataSize > CC_DH_MAX_SIZE_OF_KEYING_DATA)
536                 return CC_DH_SECRET_KEYING_DATA_SIZE_ILLEGAL_ERROR;
537 
538         /*Call the PKCS#3 get secret key function*/
539         Error = CC_DhGetSecretKey(
540                                     ClientPrvKey_ptr,
541                                     ClientPrvKeySize,
542                                     ServerPubKey_ptr,
543                                     ServerPubKeySize,
544                                     Prime_ptr,
545                                     PrimeSize,
546                                     &tmpBuff_ptr->UserPubKey,
547                                     &tmpBuff_ptr->PrimeData,
548                                     (uint8_t*)tmpBuff_ptr->TempBuff,
549                                     &SecretKeySize);
550 
551         if (Error != CC_OK)
552                 goto ExitOnError;
553 
554 
555         /*Let the keydataSize from the previous function determine the key data length in the next function*/
556         Error = CC_KdfKeyDerivFunc(
557                                      (uint8_t*)tmpBuff_ptr->TempBuff,
558                                      SecretKeySize,
559                                      otherInfo_ptr,
560                                      MakeKDFHashMode(hashMode),
561                                      MakeKDFDeriveFuncMode(DerivFunc_mode),
562                                      SecretKeyingData_ptr,
563                                      SecretKeyingDataSize);
564 
565 ExitOnError:
566 
567         CC_PalMemSetZero(tmpBuff_ptr, sizeof(CCDhTemp_t));
568 
569 
570         return Error;
571 
572 }/* END OF _DX_DH_X942_GetSecretData */
573 
574 
CC_DhX942HybridGetSecretData(uint8_t * ClientPrvKey_ptr1,size_t ClientPrvKeySize1,uint8_t * ClientPrvKey_ptr2,size_t ClientPrvKeySize2,uint8_t * ServerPubKey_ptr1,size_t ServerPubKeySize1,uint8_t * ServerPubKey_ptr2,size_t ServerPubKeySize2,uint8_t * Prime_ptr,size_t PrimeSize,CCDhOtherInfo_t * otherInfo_ptr,CCDhHashOpMode_t hashMode,CCDhDerivationFuncMode_t DerivFunc_mode,CCDhHybrTemp_t * tmpDhHybr_ptr,uint8_t * SecretKeyingData_ptr,size_t SecretKeyingDataSize)575 CEXPORT_C CCError_t CC_DhX942HybridGetSecretData(
576                                                       uint8_t            *ClientPrvKey_ptr1,
577                                                       size_t             ClientPrvKeySize1,
578                                                       uint8_t            *ClientPrvKey_ptr2,
579                                                       size_t             ClientPrvKeySize2,
580                                                       uint8_t            *ServerPubKey_ptr1,
581                                                       size_t             ServerPubKeySize1,
582                                                       uint8_t            *ServerPubKey_ptr2,
583                                                       size_t             ServerPubKeySize2,
584                                                       uint8_t            *Prime_ptr,
585                                                       size_t             PrimeSize,
586                                                       CCDhOtherInfo_t  *otherInfo_ptr,
587                                                       CCDhHashOpMode_t hashMode,
588                                                       CCDhDerivationFuncMode_t DerivFunc_mode,
589                                                       CCDhHybrTemp_t   *tmpDhHybr_ptr,
590                                                       uint8_t            *SecretKeyingData_ptr,
591                                                       size_t             SecretKeyingDataSize)
592 {
593         /* FUNCTION DECLARATIONS */
594 
595         /* The return error identifier */
596         CCError_t Error = CC_OK;
597 
598         /*The assignment to Prime size is according to the real size of the buffer SecretKeyData_ptr*/
599         size_t SecretKeyDataSize1 = PrimeSize;
600         size_t SecretKeyDataSize2 = PrimeSize;
601 
602     CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
603 
604         /* check pointers */
605         if (tmpDhHybr_ptr == NULL || SecretKeyingData_ptr == NULL)
606                 return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
607 
608         /*check that the size of derived secret key is not NULL  */
609         if (SecretKeyingDataSize == 0)
610                 return CC_DH_SECRET_KEYING_DATA_SIZE_ILLEGAL_ERROR;
611 
612         /*check that the keying data size is not too large  */
613         if (SecretKeyingDataSize > CC_DH_MAX_SIZE_OF_KEYING_DATA)
614                 return CC_DH_SECRET_KEYING_DATA_SIZE_ILLEGAL_ERROR;
615 
616         /* Note: other input parameters will be shecked in called functions */
617 
618         /* get shared secret key (value) 1 */
619         Error = CC_DhGetSecretKey(
620                                     ClientPrvKey_ptr1,
621                                     ClientPrvKeySize1,
622                                     ServerPubKey_ptr1,
623                                     ServerPubKeySize1,
624                                     Prime_ptr,
625                                     PrimeSize,
626                                     &tmpDhHybr_ptr->UserPubKey,
627                                     &tmpDhHybr_ptr->PrimeData,
628                                     (uint8_t*)&tmpDhHybr_ptr->TempBuff,
629                                     &SecretKeyDataSize1);
630         if (Error != CC_OK)
631                 goto End;
632 
633         /* get shared secret key (value) 2 */
634         Error = CC_DhGetSecretKey(
635                                     ClientPrvKey_ptr2,
636                                     ClientPrvKeySize2,
637                                     ServerPubKey_ptr2,
638                                     ServerPubKeySize2,
639                                     Prime_ptr,
640                                     PrimeSize,
641                                     &tmpDhHybr_ptr->UserPubKey,
642                                     &tmpDhHybr_ptr->PrimeData,
643                                     (uint8_t*)&tmpDhHybr_ptr->TempBuff+SecretKeyDataSize1,
644                                     &SecretKeyDataSize2);
645         if (Error != CC_OK)
646                 goto End;
647 
648         /* Derive the secret key according to the secret key size and value   *
649         *  key1||key2                                 */
650 
651 
652         Error = CC_KdfKeyDerivFunc(
653                                      (uint8_t*)&tmpDhHybr_ptr->TempBuff,
654                                      (uint16_t)(SecretKeyDataSize1 + SecretKeyDataSize2),
655                                      otherInfo_ptr,
656                                      MakeKDFHashMode(hashMode),
657                                      MakeKDFDeriveFuncMode(DerivFunc_mode),
658                                      SecretKeyingData_ptr,
659                                      SecretKeyingDataSize );
660 
661 End:
662         CC_PalMemSetZero(tmpDhHybr_ptr, sizeof(CCDhHybrTemp_t));
663 
664         return Error;
665 
666 }/* END OF CC_DhX942HybridGetSecretData */
667 
668 
CC_DhCheckPubKey(uint8_t * modP_ptr,size_t modPsizeBytes,uint8_t * orderQ_ptr,size_t orderQsizeBytes,uint8_t * pubKey_ptr,size_t pubKeySizeBytes,CCDhTemp_t * tempBuff_ptr)669 CEXPORT_C CCError_t CC_DhCheckPubKey(
670                                          uint8_t              *modP_ptr,             /*in */
671                                          size_t               modPsizeBytes,        /*in */
672                                          uint8_t              *orderQ_ptr,           /*in */
673                                          size_t               orderQsizeBytes,      /*in */
674                                          uint8_t              *pubKey_ptr,           /*in */
675                                          size_t               pubKeySizeBytes,      /*in */
676                                          CCDhTemp_t       *tempBuff_ptr          /*in */)
677 {
678 
679         /* FUNCTION DECLARATIONS */
680 
681         /* The return error identifier */
682         CCError_t Error = CC_OK;
683 
684         /* size in bits of modulus P and order Q and public key */
685         uint32_t  modPsizeBits;
686         uint32_t  orderQsizeBits;
687         uint32_t  pubKeySizeBits;
688 
689         /* comparing result */
690         int  cmpRes;
691         CCCommonCmpCounter_t cmpCounters;
692         CCDhPubKey_t  *tmpPubKey_ptr;
693 
694     CHECK_AND_RETURN_ERR_UPON_FIPS_ERROR();
695 
696         /*------------------------------- */
697         /* Step 1. Check input pointers   */
698         /*------------------------------- */
699 
700         /* check pointers: modP, generator and tempBuff. Note: other pointers may be NULL  */
701         if (modP_ptr == NULL ||
702             orderQ_ptr == NULL ||
703             pubKey_ptr == NULL ||
704             tempBuff_ptr == NULL) {
705                 return CC_DH_INVALID_ARGUMENT_POINTER_ERROR;
706         }
707         /* temp public key buffer */
708         tmpPubKey_ptr = (CCDhPubKey_t*)((void*)&tempBuff_ptr->UserPubKey.PublicKeyDbBuff);
709 
710         /*----------------------------------------------------------- */
711         /* Step 2. Calculate and check the sizes of modulus and order */
712         /*----------------------------------------------------------- */
713         /* preliminary check */
714         if (modPsizeBytes > CC_DH_MAX_VALID_KEY_SIZE_VALUE_IN_BITS / 8)
715                 return CC_DH_INVALID_MODULUS_SIZE_ERROR;
716 
717         if (orderQsizeBytes > modPsizeBytes)
718                 return CC_DH_INVALID_ORDER_SIZE_ERROR;
719 
720         if (pubKeySizeBytes > modPsizeBytes)
721                 return CC_DH_INVALID_PUBLIC_KEY_SIZE_ERROR;
722 
723 
724         /* convert input data into LSW arrays */
725         /*------------------------------------*/
726 // RL - restrict zeroing
727         CC_PalMemSetZero( tempBuff_ptr, sizeof(CCDhTemp_t) );
728 
729         Error = CC_CommonConvertMsbLsbBytesToLswMswWords(tmpPubKey_ptr->n, modPsizeBytes, modP_ptr, modPsizeBytes);
730         if (Error) {
731                 Error = CC_DH_INVALID_MODULUS_SIZE_ERROR;
732                 return Error;
733     }
734 
735         Error = CC_CommonConvertMsbLsbBytesToLswMswWords(tmpPubKey_ptr->e, modPsizeBytes, orderQ_ptr, orderQsizeBytes);
736         if (Error) {
737                 Error = CC_DH_INVALID_ORDER_SIZE_ERROR;
738                 goto End;
739     }
740 
741         Error = CC_CommonConvertMsbLsbBytesToLswMswWords(tempBuff_ptr->PrimeData.DataIn, modPsizeBytes, pubKey_ptr, pubKeySizeBytes);
742         if (Error) {
743                 Error = CC_DH_INVALID_PUBLIC_KEY_SIZE_ERROR;
744                 goto End;
745     }
746 
747         /* calculate sizes in bits of input parameters */
748         modPsizeBits   = CC_MIN(8*modPsizeBytes, CC_CommonGetWordsCounterEffectiveSizeInBits(tmpPubKey_ptr->n, (uint16_t)modPsizeBytes/4));
749         orderQsizeBits = CC_MIN(8*orderQsizeBytes, CC_CommonGetWordsCounterEffectiveSizeInBits(tmpPubKey_ptr->e, (uint16_t)(orderQsizeBytes+3)/4));
750         pubKeySizeBits = CC_MIN(8*pubKeySizeBytes, CC_CommonGetWordsCounterEffectiveSizeInBits(tempBuff_ptr->PrimeData.DataIn, (uint16_t)(pubKeySizeBytes+3)/4));
751 
752         /* check sizes */
753         if (modPsizeBits < CC_DH_MIN_VALID_KEY_SIZE_VALUE_IN_BITS ||
754             modPsizeBits % 256 != 0 ||
755             modPsizeBits > CC_DH_MAX_VALID_KEY_SIZE_VALUE_IN_BITS) {
756                 Error = CC_DH_INVALID_MODULUS_SIZE_ERROR;
757                 goto End;
758         }
759 
760         if (orderQsizeBits < CC_DH_SEED_MIN_SIZE_IN_BITS ||
761             orderQsizeBits % 32 != 0) {
762                 Error = CC_DH_INVALID_ORDER_SIZE_ERROR;
763                 goto End;
764         }
765 
766         if (pubKeySizeBits > modPsizeBits ||
767             pubKeySizeBits <= 1) {
768                 Error = CC_DH_INVALID_PUBLIC_KEY_SIZE_ERROR;
769                 goto End;
770         }
771 
772 
773         /*----------------------------------------------------------- */
774         /* Step 2. Check value of public key:   pubKey < P-1          */
775         /*         Note: pubKey > 1 already is checked above          */
776         /*----------------------------------------------------------- */
777 
778         /* decrement modulus in temp buffer n (in little endianness). Note: the modulus is odd */
779         tmpPubKey_ptr->n[0] -= 1;
780 
781         /* compare pub key saved in temp buff e to P-1 */
782         cmpCounters = CC_CommonCmpLsWordsUnsignedCounters(
783                                                             tmpPubKey_ptr->e, /* counter1 - pubKey */
784                                                             (uint16_t)(pubKeySizeBytes+3)/4,
785                                                             tmpPubKey_ptr->n, /* counter2 - (P-1) */
786                                                             (uint16_t)modPsizeBytes/4);
787 
788         if (cmpCounters != CC_COMMON_CmpCounter2GreaterThenCounter1) {
789                 Error = CC_DH_INVALID_PUBLIC_KEY_ERROR;
790                 goto End;
791         }
792 
793         /*----------------------------------------------------*/
794         /* Step 4. Initialization of PubKey and PrivData      */
795         /*         structures for exponentiation              */
796         /*----------------------------------------------------*/
797 
798         /* increment (revert) modulus in temp buffer n (in little endianness) */
799         tmpPubKey_ptr->n[0] += 1;
800 
801         /* set modulus and exponent sizes in DH_PubKey structure  */
802         tmpPubKey_ptr->nSizeInBits = modPsizeBits;
803         tmpPubKey_ptr->eSizeInBits = orderQsizeBits;
804 
805         /*  initialize the H value in LLF of PubKey for exponentiation  */
806         Error = RsaInitPubKeyDb( tmpPubKey_ptr );
807 
808         if (Error != CC_OK) {
809                 Error = CC_DH_INVALID_PUBLIC_KEY_ERROR;
810                 goto End;
811         }
812 
813         /*-----------------------------------------------------------*/
814         /* Step 3. Calculate Res = Key ^ Q mod P , if Res == 1,      */
815         /*         then key is valid, else non valid                 */
816         /*-----------------------------------------------------------*/
817 
818         /* exponentiation DataOut = DataIn ^ exp mod n */
819         Error = RsaExecPubKeyExp(tmpPubKey_ptr, &tempBuff_ptr->PrimeData);
820 
821         if (Error != CC_OK) {
822                 Error = CC_DH_INVALID_PUBLIC_KEY_ERROR;
823                 goto End;
824         }
825 
826         /* set 1 to PubKey_ptr->n buffer (used as temp buffer) */
827         CC_PalMemSetZero((uint8_t*)&tmpPubKey_ptr->n, modPsizeBytes);
828         tmpPubKey_ptr->n[0] = 1;
829 
830         /* compare DataOut to 1: */
831         cmpRes = CC_CommonCmpLsWordsUnsignedCounters(
832                                                        tempBuff_ptr->PrimeData.DataOut, modPsizeBytes/4, tmpPubKey_ptr->n, modPsizeBytes/4);
833 
834         if (cmpRes != 0)  {/* if Res != 1 */
835                 Error = CC_DH_INVALID_PUBLIC_KEY_ERROR;
836                 goto End;
837     }
838 
839 End:
840 
841         /* clean temp buffers */
842         CC_PalMemSetZero(tempBuff_ptr, sizeof(CCDhTemp_t));
843 
844         return Error;
845 }
846 
847