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