ReactOS 0.4.17-dev-1005-g171e1de
eckey.c
Go to the documentation of this file.
1//
2// eckey.c Functions for the ECKEY object
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6//
7
8#include "precomp.h"
9
13{
14 PVOID p;
15 SIZE_T cb;
17
19
21
22 if ( p==NULL )
23 {
24 goto cleanup;
25 }
26
28
30 return res;
31}
32
33VOID
36{
37 SYMCRYPT_CHECK_MAGIC( pkObj );
38 SymCryptEckeyWipe( pkObj );
39 SymCryptCallbackFree( pkObj );
40}
41
45{
46 //
47 // From symcrypt_internal.h we have:
48 // - sizeof results are upper bounded by 2^19
49 // - SYMCRYPT_SCRATCH_BYTES results are upper bounded by 2^27 (including RSA and ECURVE)
50 // - SymCryptSizeofEcpointFromCurve outputs the size of up to 4 modelements + some overhead
51 // Thus the following calculation does not overflow the result.
52 //
54}
55
62{
63 PSYMCRYPT_ECKEY pkObj = NULL;
65
67 SIZE_T cbPrivateKey = SymCryptSizeofIntFromDigits( privateKeyDigits );
68
69 UNREFERENCED_PARAMETER( cbBuffer ); // only referenced in ASSERTs...
70
73
75 cbPublicKey +
76 cbPrivateKey );
77
79
80 pkObj = (PSYMCRYPT_ECKEY) pbBuffer;
81
82 pkObj->fAlgorithmInfo = 0;
83 pkObj->hasPrivateKey = FALSE;
84 pkObj->pCurve = pCurve;
85
86 pkObj->poPublicKey = SymCryptEcpointCreate(
87 pbBuffer + sizeof(SYMCRYPT_ECKEY),
88 cbPublicKey,
89 pCurve );
90 SYMCRYPT_ASSERT( pkObj->poPublicKey != NULL );
91
92 pkObj->piPrivateKey = SymCryptIntCreate(
93 pbBuffer + sizeof(SYMCRYPT_ECKEY) + cbPublicKey,
94 cbPrivateKey,
95 privateKeyDigits );
96 SYMCRYPT_ASSERT( pkObj->piPrivateKey );
97
98 // Setting the magic
99 SYMCRYPT_SET_MAGIC( pkObj );
100
101 return pkObj;
102}
103
104VOID
107 _Inout_ PSYMCRYPT_ECKEY pkEckey )
108{
109 SymCryptIntSetValueUint32( 0, pkEckey->piPrivateKey );
110 pkEckey->hasPrivateKey = FALSE;
111}
112
113VOID
116{
117 // Wipe the whole structure in one go.
118 SymCryptWipe( pkDst, SymCryptSizeofEckeyFromCurve( pkDst->pCurve ) );
119}
120
121VOID
124 _Out_ PSYMCRYPT_ECKEY pkDst )
125{
126 //
127 // in-place copy is somewhat common...
128 //
129 if( pkSrc != pkDst )
130 {
131 // Copy the fAlgorithmInfo flags
132 pkDst->fAlgorithmInfo = pkSrc->fAlgorithmInfo;
133
134 // Copy the hasPrivateKey flag
135 pkDst->hasPrivateKey = pkSrc->hasPrivateKey;
136
137 // Copy the public key
138 SymCryptEcpointCopy( pkSrc->pCurve, pkSrc->poPublicKey, pkDst->poPublicKey );
139
140 // Copy the private key
141 SymCryptIntCopy( pkSrc->piPrivateKey, pkDst->piPrivateKey );
142 }
143}
144
145UINT32
148 _In_ PCSYMCRYPT_ECKEY pkEckey,
149 _In_ SYMCRYPT_ECPOINT_FORMAT ecPointFormat )
150{
151 //
152 // From symcrypt_internal.h we have:
153 // - sizeof results are upper bounded by 2^19
154 // - SYMCRYPT_SCRATCH_BYTES results are upper bounded by 2^27 (including RSA and ECURVE)
155 // - SymCryptEcpointFormatNumberofElements returns up to 4 elements.
156 //
157 // Thus the following calculation does not overflow cbScratch.
158 //
159 return SymCryptEcpointFormatNumberofElements[ecPointFormat] * SymCryptEcurveSizeofFieldElement( pkEckey->pCurve );
160}
161
162UINT32
165{
166 return SymCryptEcurveSizeofScalarMultiplier( pkEckey->pCurve );
167}
168
172{
173 return pkEckey->hasPrivateKey;
174}
175
176#define SYMCRYPT_FLAG_ECKEY_PUBLIC_KEY_ORDER_VALIDATION (0x1)
177
181 _In_ PCSYMCRYPT_ECKEY pEckey,
185{
186 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
187
188 PCSYMCRYPT_ECURVE pCurve = pEckey->pCurve;
189
190 PSYMCRYPT_ECPOINT poNPub = NULL;
192
193 // This is an excessive amount of space to require, but all callers can currently provide it, and it's easy to phrase
195
196 SYMCRYPT_ASSERT( cbScratch >= cbNPub );
197
198 // Check if Public key is O
199 if ( SymCryptEcpointIsZero( pCurve, pEckey->poPublicKey, pbScratch, cbScratch ) )
200 {
201 return SYMCRYPT_INVALID_ARGUMENT;
202 }
203
204 // Public key is represented by Modelements of the underlying finite field for the curve
205 // If we have reached this point we have either:
206 // Constructed the Public key to have coordinates in the field (Generate case), or
207 // Verified the Public key has coordinates in the field (SetValue case)
208
209 // Check that Public key is on the curve
210 // Skip check for Montgomery curves as we do not have an EcpointOnCurve function for them
212 !SymCryptEcpointOnCurve( pCurve, pEckey->poPublicKey, pbScratch, cbScratch ) )
213 {
214 return SYMCRYPT_INVALID_ARGUMENT;
215 }
216
217 // Perform validation that Public key is in a subgroup of order GOrd.
219 {
220 if ( SymCryptIntIsEqualUint32( pCurve->H, 1 ) )
221 {
222 // If cofactor is 1 then to validate that Public key has order GOrd
223 // it is sufficient to validate Public key is on the curve
224 // We just performed this check - so we are done.
225 }
226 else
227 {
228 // Ensure GOrd*(Public key) == O
229 poNPub = SymCryptEcpointCreate( pbScratch, cbNPub, pCurve );
230 pbScratch += cbNPub;
231 cbScratch -= cbNPub;
232
233 SYMCRYPT_ASSERT( poNPub != NULL );
234
235 // Do the multiplication
236 scError = SymCryptEcpointScalarMul(
237 pCurve,
239 pEckey->poPublicKey,
240 0, // Do not multiply by cofactor!
241 poNPub,
242 pbScratch,
243 cbScratch );
244 if ( scError != SYMCRYPT_NO_ERROR )
245 {
246 return scError;
247 }
248
249 if ( !SymCryptEcpointIsZero( pCurve, poNPub, pbScratch, cbScratch ) )
250 {
251 return SYMCRYPT_INVALID_ARGUMENT;
252 }
253 }
254 }
255
256 return SYMCRYPT_NO_ERROR;
257}
258
262 _In_reads_bytes_( cbPrivateKey )
263 PCBYTE pbPrivateKey,
264 SIZE_T cbPrivateKey,
265 _In_reads_bytes_( cbPublicKey )
266 PCBYTE pbPublicKey,
267 SIZE_T cbPublicKey,
268 SYMCRYPT_NUMBER_FORMAT numFormat,
269 SYMCRYPT_ECPOINT_FORMAT ecPointFormat,
271 _Inout_ PSYMCRYPT_ECKEY pEckey )
272{
273 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
274 PBYTE pbScratch = NULL;
275 UINT32 cbScratch = 0;
276 PBYTE pbScratchInternal = NULL;
277 UINT32 cbScratchInternal = 0;
278
279 PCSYMCRYPT_ECURVE pCurve = pEckey->pCurve;
280
281 PSYMCRYPT_ECPOINT poTmp = NULL;
282 UINT32 cbTmp = 0;
283
284 PSYMCRYPT_INT piTmpInteger = NULL;
285 UINT32 cbTmpInteger = 0;
286 PSYMCRYPT_MODELEMENT peTmpModElement = NULL;
287 UINT32 cbTmpModElement = pCurve->cbModElement;
288
290
292
293 // Ensure caller has specified what algorithm(s) the key will be used with
295 // Make sure only allowed flags are specified
297
298 if ( ( ( flags & ~allowedFlags ) != 0 ) ||
299 ( ( flags & algorithmFlags ) == 0 ) )
300 {
301 scError = SYMCRYPT_INVALID_ARGUMENT;
302 goto cleanup;
303 }
304
305 // Check that minimal validation flag only specified with no fips
306 if ( ( ( flags & SYMCRYPT_FLAG_KEY_NO_FIPS ) == 0 ) &&
308 {
309 scError = SYMCRYPT_INVALID_ARGUMENT;
310 goto cleanup;
311 }
312
313 if ( ( flags & SYMCRYPT_FLAG_KEY_NO_FIPS ) != 0 )
314 {
315 fValidatePublicKeyOrder = 0;
316 }
317
318 if ( ( ( cbPrivateKey == 0 ) && ( cbPublicKey == 0 ) ) ||
319 ( ( cbPrivateKey != 0 ) && ( cbPrivateKey != SymCryptEcurveSizeofScalarMultiplier( pEckey->pCurve ) ) ) ||
320 ( ( cbPublicKey != 0 ) && ( cbPublicKey != SymCryptEckeySizeofPublicKey( pEckey, ecPointFormat ) ) ) )
321 {
322 scError = SYMCRYPT_INVALID_ARGUMENT;
323 goto cleanup;
324 }
325
326 // Allocate scratch space
328 pbScratch = SymCryptCallbackAlloc( cbScratch );
329 if ( pbScratch == NULL )
330 {
331 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
332 goto cleanup;
333 }
334
335 if ( pbPrivateKey != NULL )
336 {
337 //
338 // Private key calculations
339 //
340
341 pbScratchInternal = pbScratch;
342 cbScratchInternal = cbScratch;
343
344 // Allocate the integer
345 cbTmpInteger = SymCryptSizeofIntFromDigits( privateKeyDigits );
346 piTmpInteger = SymCryptIntCreate( pbScratchInternal, cbTmpInteger, privateKeyDigits );
347 SYMCRYPT_ASSERT( piTmpInteger != NULL );
348
349 pbScratchInternal += cbTmpInteger;
350 cbScratchInternal -= cbTmpInteger;
351
352 // Allocate the modelement
353 peTmpModElement = SymCryptModElementCreate( pbScratchInternal, cbTmpModElement, pCurve->GOrd );
354 SYMCRYPT_ASSERT( peTmpModElement != NULL );
355
356 pbScratchInternal += cbTmpModElement;
357 cbScratchInternal -= cbTmpModElement;
358
359 // Get the "raw" private key
360 scError = SymCryptIntSetValue( pbPrivateKey, cbPrivateKey, numFormat, piTmpInteger );
361 if (scError != SYMCRYPT_NO_ERROR)
362 {
363 goto cleanup;
364 }
365
366 // Validation steps
368 {
369 // Perform range validation on imported Private key if it is in canonical format
370 if ( pCurve->PrivateKeyDefaultFormat == SYMCRYPT_ECKEY_PRIVATE_FORMAT_CANONICAL )
371 {
372 // Check if Private key is greater than or equal to GOrd
373 if ( !SymCryptIntIsLessThan( piTmpInteger, SymCryptIntFromModulus( pCurve->GOrd ) ) )
374 {
375 scError = SYMCRYPT_INVALID_ARGUMENT;
376 goto cleanup;
377 }
378 }
379
380 // "TimesH" formats
381 // IntGetBits requirements:
382 // We know that coFactorPower is up to SYMCRYPT_ECURVE_MAX_COFACTOR_POWER. Thus
383 // less than 32 and less than the digits size in bits.
384 if ( (pCurve->coFactorPower>0) &&
385 (pCurve->PrivateKeyDefaultFormat == SYMCRYPT_ECKEY_PRIVATE_FORMAT_DIVH_TIMESH) &&
386 (SymCryptIntGetBits( piTmpInteger, 0, pCurve->coFactorPower) != 0) )
387 {
388 scError = SYMCRYPT_INVALID_ARGUMENT;
389 goto cleanup;
390 }
391
392
393 // High bit restrictions
394 // IntGetBits requirements:
395 // Satisfied by asserting that
396 // HighBitRestrictionPosition + HighBitRestrictionNumOfBits <= GOrdBitsize + coFactorPower
397 // during EcurveAllocate.
398 if ( (pCurve->HighBitRestrictionNumOfBits>0) &&
400 piTmpInteger,
401 pCurve->HighBitRestrictionPosition,
402 pCurve->HighBitRestrictionNumOfBits) != pCurve->HighBitRestrictionValue) )
403 {
404 scError = SYMCRYPT_INVALID_ARGUMENT;
405 goto cleanup;
406 }
407 }
408
409 // Convert the private key to "DivH" format
410 if (pCurve->coFactorPower>0)
411 {
412 // "TimesH" format: Divide the input private key with the cofactor
413 // by shifting right the appropriate number of bits
414 if (pCurve->PrivateKeyDefaultFormat == SYMCRYPT_ECKEY_PRIVATE_FORMAT_DIVH_TIMESH)
415 {
416 SymCryptIntDivPow2( piTmpInteger, pCurve->coFactorPower, piTmpInteger );
417 }
418
419 // "Canonical" format: Divide by h modulo GOrd
420 if (pCurve->PrivateKeyDefaultFormat == SYMCRYPT_ECKEY_PRIVATE_FORMAT_CANONICAL)
421 {
422 SymCryptIntToModElement( piTmpInteger, pCurve->GOrd, peTmpModElement, pbScratchInternal, cbScratchInternal );
423 SymCryptModDivPow2( pCurve->GOrd, peTmpModElement, pCurve->coFactorPower, peTmpModElement, pbScratchInternal, cbScratchInternal );
424 SymCryptModElementToInt( pCurve->GOrd, peTmpModElement, piTmpInteger, pbScratchInternal, cbScratchInternal );
425 }
426 }
427
428 // Divide the input private key since it could be larger than subgroup order
430 piTmpInteger,
432 NULL,
433 piTmpInteger,
434 pbScratchInternal,
435 cbScratchInternal );
436
437 // Check if Private key is 0 after dividing it by the subgroup order
438 // Other part of range validation - perform unconditionally as it is cheap
439 // and it never makes sense for private key to be 0 intentionally
440 if (SymCryptIntIsEqualUint32( piTmpInteger, 0 ))
441 {
442 scError = SYMCRYPT_INVALID_ARGUMENT;
443 goto cleanup;
444 }
445
446 // Copy into the ECKEY
447 SymCryptIntCopy( piTmpInteger, pEckey->piPrivateKey );
448
449 pEckey->hasPrivateKey = TRUE;
450 }
451
452 if ( pbPublicKey != NULL )
453 {
454 scError = SymCryptEcpointSetValue(
455 pCurve,
456 pbPublicKey,
457 cbPublicKey,
458 numFormat,
459 ecPointFormat,
460 pEckey->poPublicKey,
462 pbScratch,
463 cbScratch );
464 if ( scError != SYMCRYPT_NO_ERROR )
465 {
466 goto cleanup;
467 }
468
469 // Perform Public key validation on imported Public key.
471 {
473 pEckey,
474 fValidatePublicKeyOrder,
475 pbScratch,
476 cbScratch );
477 if ( scError != SYMCRYPT_NO_ERROR )
478 {
479 goto cleanup;
480 }
481 }
482 }
483
484 // Calculating the public key if no key was provided
485 // or if needed for keypair regeneration validation
486 if ( (pbPublicKey==NULL) ||
487 ( ( ( flags & SYMCRYPT_FLAG_KEY_NO_FIPS ) == 0 ) &&
488 (pbPrivateKey!=NULL) && (pbPublicKey!=NULL) ) )
489 {
490 // Calculate the public key from the private key
491 pbScratchInternal = pbScratch;
492 cbScratchInternal = cbScratch;
493
494 // By default calculate the Public key directly where it will be persisted
495 poTmp = pEckey->poPublicKey;
496
497 if ( pbPublicKey != NULL )
498 {
499 // If doing regeneration validation calculate the Public key in scratch
501 poTmp = SymCryptEcpointCreate( pbScratchInternal, cbTmp, pCurve );
502 pbScratchInternal += cbTmp;
503 cbScratchInternal -= cbTmp;
504 }
505
506 SYMCRYPT_ASSERT( poTmp != NULL );
507
508 // Always multiply by the cofactor since the internal format is "DIVH"
509 scError = SymCryptEcpointScalarMul(
510 pCurve,
511 pEckey->piPrivateKey,
512 NULL,
514 poTmp,
515 pbScratchInternal,
516 cbScratchInternal );
517 if ( scError != SYMCRYPT_NO_ERROR )
518 {
519 goto cleanup;
520 }
521
522 if ( pbPublicKey != NULL )
523 {
524 if ( !SymCryptEcpointIsEqual( pCurve, poTmp, pEckey->poPublicKey, 0, pbScratchInternal, cbScratchInternal ) )
525 {
526 scError = SYMCRYPT_INVALID_ARGUMENT;
527 goto cleanup;
528 }
529 }
530 else if ( ( flags & SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION ) == 0 )
531 {
532 // Perform Public key validation on generated Public key.
534 pEckey,
535 fValidatePublicKeyOrder,
536 pbScratch,
537 cbScratch );
538 if ( scError != SYMCRYPT_NO_ERROR )
539 {
540 goto cleanup;
541 }
542 }
543 }
544
545 pEckey->fAlgorithmInfo = flags; // We want to track all of the flags in the Eckey
546
547 if ( ( flags & SYMCRYPT_FLAG_KEY_NO_FIPS ) == 0 )
548 {
549 if ( ( flags & SYMCRYPT_FLAG_ECKEY_ECDSA ) != 0 )
550 {
551 // Ensure ECDSA algorithm selftest is run before first use of ECDSA algorithm
555
556 // PCT does not need to be run on import - mark it as done
557 pEckey->fAlgorithmInfo |= SYMCRYPT_PCT_ECDSA;
558 }
559
560 if ( ( flags & SYMCRYPT_FLAG_ECKEY_ECDH ) != 0 )
561 {
565 }
566 }
567
568cleanup:
569
570 if ( pbScratch != NULL )
571 {
572 SymCryptWipe( pbScratch, cbScratch );
573 SymCryptCallbackFree( pbScratch );
574 }
575
576 return scError;
577}
578
582 _In_ PCSYMCRYPT_ECKEY pEckey,
583 _Out_writes_bytes_( cbPrivateKey )
584 PBYTE pbPrivateKey,
585 SIZE_T cbPrivateKey,
586 _Out_writes_bytes_( cbPublicKey )
587 PBYTE pbPublicKey,
588 SIZE_T cbPublicKey,
589 SYMCRYPT_NUMBER_FORMAT numFormat,
590 SYMCRYPT_ECPOINT_FORMAT ecPointFormat,
591 UINT32 flags )
592{
593 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
594 PBYTE pbScratch = NULL;
595 UINT32 cbScratch = 0;
596 PBYTE pbScratchInternal = NULL;
597 UINT32 cbScratchInternal = 0;
598
599 PCSYMCRYPT_ECURVE pCurve = pEckey->pCurve;
600
601 PSYMCRYPT_INT piTmpInteger = NULL;
602 UINT32 cbTmpInteger = 0;
603 PSYMCRYPT_MODELEMENT peTmpModElement = NULL;
604 UINT32 cbTmpModElement = pCurve->cbModElement;
605
607
608 SYMCRYPT_ASSERT( (cbPrivateKey==0) || (cbPrivateKey == SymCryptEcurveSizeofScalarMultiplier( pEckey->pCurve )) );
609 SYMCRYPT_ASSERT( (cbPublicKey==0) || (cbPublicKey == SymCryptEckeySizeofPublicKey( pEckey, ecPointFormat)) );
610
611 // Make sure we only specify the correct flags
612 if (flags != 0)
613 {
614 scError = SYMCRYPT_INVALID_ARGUMENT;
615 goto cleanup;
616 }
617
618 // Allocate scratch space
620 pbScratch = SymCryptCallbackAlloc( cbScratch );
621 if ( pbScratch == NULL )
622 {
623 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
624 goto cleanup;
625 }
626
627 pbScratchInternal = pbScratch;
628 cbScratchInternal = cbScratch;
629
630 // Allocate the integer
631 cbTmpInteger = SymCryptSizeofIntFromDigits( privateKeyDigits );
632 piTmpInteger = SymCryptIntCreate( pbScratchInternal, cbTmpInteger, privateKeyDigits );
633 SYMCRYPT_ASSERT( piTmpInteger != NULL );
634
635 pbScratchInternal += cbTmpInteger;
636 cbScratchInternal -= cbTmpInteger;
637
638 // Allocate the modelement
639 peTmpModElement = SymCryptModElementCreate( pbScratchInternal, cbTmpModElement, pCurve->GOrd );
640 SYMCRYPT_ASSERT( peTmpModElement != NULL );
641
642 pbScratchInternal += cbTmpModElement;
643 cbScratchInternal -= cbTmpModElement;
644
645 if ((cbPrivateKey == 0) && (cbPublicKey == 0))
646 {
647 scError = SYMCRYPT_INVALID_ARGUMENT;
648 goto cleanup;
649 }
650
651 if (cbPrivateKey != 0)
652 {
653 if (!pEckey->hasPrivateKey)
654 {
655 scError = SYMCRYPT_INVALID_BLOB;
656 goto cleanup;
657 }
658
659 // If this keypair may be used in ECDSA, and does not have the no FIPS flag, run the PCT if
660 // it has not already been run
661 if ( ((pEckey->fAlgorithmInfo & SYMCRYPT_FLAG_ECKEY_ECDSA) != 0) &&
662 ((pEckey->fAlgorithmInfo & SYMCRYPT_FLAG_KEY_NO_FIPS) == 0) )
663 {
666 pEckey,
668 }
669
670 // Copy the key into the temporary integer
671 SymCryptIntCopy( pEckey->piPrivateKey, piTmpInteger );
672
673 // Convert the "DivH" format into the external format
674 if (pCurve->coFactorPower>0)
675 {
676 // For the "Canonical" format: Multiply the integer by h
677 // and then take the result modulo GOrd
678 if (pCurve->PrivateKeyDefaultFormat == SYMCRYPT_ECKEY_PRIVATE_FORMAT_CANONICAL)
679 {
680 SymCryptIntMulPow2( piTmpInteger, pCurve->coFactorPower, piTmpInteger );
682 piTmpInteger,
684 NULL,
685 piTmpInteger,
686 pbScratchInternal,
687 cbScratchInternal );
688 }
689
690 // For the "TimesH" format: Multiply the integer by h again by shifting
691 if (pCurve->PrivateKeyDefaultFormat == SYMCRYPT_ECKEY_PRIVATE_FORMAT_DIVH_TIMESH)
692 {
693 SymCryptIntMulPow2( piTmpInteger, pCurve->coFactorPower, piTmpInteger );
694 }
695 }
696
697 scError = SymCryptIntGetValue( piTmpInteger, pbPrivateKey, cbPrivateKey, numFormat );
698 if (scError != SYMCRYPT_NO_ERROR)
699 {
700 goto cleanup;
701 }
702 }
703
704 if (cbPublicKey != 0)
705 {
706 scError = SymCryptEcpointGetValue(
707 pCurve,
708 pEckey->poPublicKey,
709 numFormat,
710 ecPointFormat,
711 pbPublicKey,
712 cbPublicKey,
714 pbScratch,
715 cbScratch );
716 }
717
718cleanup:
719
720 if ( pbScratch != NULL )
721 {
722 SymCryptWipe( pbScratch, cbScratch );
723 SymCryptCallbackFree( pbScratch );
724 }
725
726 return scError;
727}
728
729#define SYMCRYPT_ECPOINT_SET_RANDOM_MAX_TRIES (1000)
730
735 _Inout_ PSYMCRYPT_ECKEY pEckey )
736{
737 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
738 PBYTE pbScratch = NULL;
739 UINT32 cbScratch = 0;
740 PBYTE pbScratchInternal = NULL;
741 UINT32 cbScratchInternal = 0;
742
743 PCSYMCRYPT_ECURVE pCurve = pEckey->pCurve;
744
745 PSYMCRYPT_ECPOINT poTmp = NULL;
746 UINT32 cbTmp = 0;
747
749
750 PSYMCRYPT_MODELEMENT peScalar = NULL;
751 PSYMCRYPT_INT piScalar = NULL;
752 UINT32 cbScalar = 0;
753
754 UINT32 highBitRestrictionPosition = pCurve->HighBitRestrictionPosition;
755
756 // Ensure caller has specified what algorithm(s) the key will be used with
758 // Make sure only allowed flags are specified
759 UINT32 allowedFlags = SYMCRYPT_FLAG_KEY_NO_FIPS | algorithmFlags;
760
761 if ( ( ( flags & ~allowedFlags ) != 0 ) ||
762 ( ( flags & algorithmFlags ) == 0 ) )
763 {
764 scError = SYMCRYPT_INVALID_ARGUMENT;
765 goto cleanup;
766 }
767
768 //
769 // From symcrypt_internal.h we have:
770 // - sizeof results are upper bounded by 2^19
771 // - SYMCRYPT_SCRATCH_BYTES results are upper bounded by 2^27 (including RSA and ECURVE)
772 // Thus the following calculation does not overflow cbScratch.
773 //
775 pbScratch = SymCryptCallbackAlloc( cbScratch );
776 if ( pbScratch == NULL )
777 {
778 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
779 goto cleanup;
780 }
781
782 // Allocating temporaries
783 pbScratchInternal = pbScratch;
784 cbScratchInternal = cbScratch;
785
786 peScalar = SymCryptModElementCreate( pbScratchInternal, pCurve->cbModElement, pCurve->GOrd );
787 SYMCRYPT_ASSERT( peScalar != NULL );
788
789 pbScratchInternal += pCurve->cbModElement;
790 cbScratchInternal -= pCurve->cbModElement;
791
793 piScalar = SymCryptIntCreate( pbScratchInternal, cbScalar, SymCryptEcurveDigitsofScalarMultiplier(pCurve) );
794
795 pbScratchInternal += cbScalar;
796 cbScratchInternal -= cbScalar;
797
798 // Shift the high bit position if the format is "TIMESH"
799 // Note: Do not actually multiply the integer as we will check if it is
800 // less than the group order
801 if (pCurve->PrivateKeyDefaultFormat == SYMCRYPT_ECKEY_PRIVATE_FORMAT_DIVH_TIMESH)
802 {
803 highBitRestrictionPosition -= pCurve->coFactorPower;
804 }
805
806 // Main loop
807 do
808 {
809 // We perform Private key range validation by construction
810 // Setting a random mod element in the [1, SubgroupOrder-1] set
811 // This will be the "DivH" format of the private key. This means
812 // that PublicKey = h * PrivateKey * G
814 pCurve->GOrd,
815 peScalar,
817 pbScratchInternal,
818 cbScratchInternal );
819
820 // Converting to "canonical" format
821 if (pCurve->PrivateKeyDefaultFormat == SYMCRYPT_ECKEY_PRIVATE_FORMAT_CANONICAL)
822 {
823 for (UINT32 i=0; i<pCurve->coFactorPower; i++)
824 {
825 SymCryptModAdd( pCurve->GOrd, peScalar, peScalar, peScalar, pbScratchInternal, cbScratchInternal );
826 }
827 }
828
829 // Set the temporary scalar to verify the format
830 SymCryptModElementToInt( pCurve->GOrd, peScalar, piScalar, pbScratchInternal, cbScratchInternal );
831
832 if (pCurve->HighBitRestrictionNumOfBits > 0)
833 {
834 // Set the desired bits
836 piScalar,
837 pCurve->HighBitRestrictionValue,
838 highBitRestrictionPosition,
839 pCurve->HighBitRestrictionNumOfBits );
840
841 // Make sure we didn't exceed the group order
843 piScalar,
845 {
846 break;
847 }
848 }
849 else
850 {
851 // No high bit restriction was specified
852 break;
853 }
854
855 cntr--;
856 }
857 while (cntr>0);
858
859 if (cntr <= 0)
860 {
861 scError = SYMCRYPT_INVALID_ARGUMENT;
862 goto cleanup;
863 }
864
865 // Here piScalar has a private key that satisfies the restriction(s)
866 // Move it to the modelement
867 SymCryptIntToModElement( piScalar, pCurve->GOrd, peScalar, pbScratchInternal, cbScratchInternal );
868
869 // Convert the private key back to "DIVH" format
870 if (pCurve->PrivateKeyDefaultFormat == SYMCRYPT_ECKEY_PRIVATE_FORMAT_CANONICAL)
871 {
872 SymCryptModDivPow2( pCurve->GOrd, peScalar, pCurve->coFactorPower, peScalar, pbScratchInternal, cbScratchInternal );
873 }
874
875 // Set the private key
876 SymCryptModElementToInt( pCurve->GOrd, peScalar, pEckey->piPrivateKey, pbScratchInternal, cbScratchInternal );
877
878 // Do the multiplication (pass over the entire scratch space as it is not needed anymore)
879 scError = SymCryptEcpointScalarMul(
880 pCurve,
881 pEckey->piPrivateKey,
882 NULL,
884 pEckey->poPublicKey,
885 pbScratch,
886 cbScratch );
887 if ( scError != SYMCRYPT_NO_ERROR )
888 {
889 goto cleanup;
890 }
891
892 // Perform range and public key order validation on generated Public key.
893 if ( (flags & SYMCRYPT_FLAG_KEY_NO_FIPS) == 0 )
894 {
895 // Perform Public key validation.
896 // Always perform range validation and validation that Public key is in subgroup of order GOrd
898 pEckey,
900 pbScratch,
901 cbScratch );
902 if ( scError != SYMCRYPT_NO_ERROR )
903 {
904 goto cleanup;
905 }
906 }
907
908 pEckey->hasPrivateKey = TRUE;
909
910 pEckey->fAlgorithmInfo = flags; // We want to track all of the flags in the Eckey
911
912 if ( (flags & SYMCRYPT_FLAG_KEY_NO_FIPS) == 0 )
913 {
914 if( ( flags & SYMCRYPT_FLAG_ECKEY_ECDSA ) != 0 )
915 {
916 // Ensure ECDSA algorithm selftest is run before first use of ECDSA algorithm
920 }
921
922 if( ( flags & SYMCRYPT_FLAG_ECKEY_ECDH ) != 0 )
923 {
924 // Ensure we have run the algorithm selftest at least once.
928
929 // Run PCT eagerly so it only needs to be defined here
930 // The important case for performance is ECDH key generation
931
932 // ECDH PCT per SP80056a-rev3 5.6.2.1.4 b)
933 // Recompute the public key from the private key
934 // Option a) appears to be explicitly overruled by 140-3 IG
935 pbScratchInternal = pbScratch;
936 cbScratchInternal = cbScratch;
937
939 poTmp = SymCryptEcpointCreate( pbScratchInternal, cbTmp, pCurve );
940 pbScratchInternal += cbTmp;
941 cbScratchInternal -= cbTmp;
942
943 SYMCRYPT_ASSERT( poTmp != NULL );
944
945 // Always multiply by the cofactor since the internal format is "DIVH"
946 scError = SymCryptEcpointScalarMul(
947 pCurve,
948 pEckey->piPrivateKey,
949 NULL,
951 poTmp,
952 pbScratchInternal,
953 cbScratchInternal );
954 if ( scError != SYMCRYPT_NO_ERROR )
955 {
956 goto cleanup;
957 }
958
959 SYMCRYPT_FIPS_ASSERT( SymCryptEcpointIsEqual( pCurve, poTmp, pEckey->poPublicKey, 0, pbScratchInternal, cbScratchInternal ) );
960 }
961 }
962
963cleanup:
964
965 if ( pbScratch != NULL )
966 {
967 SymCryptWipe( pbScratch, cbScratch );
968 SymCryptCallbackFree( pbScratch );
969 }
970
971 return scError;
972}
973
978 UINT32 flags )
979{
980 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
981
982 // Ensure caller has specified what algorithm(s) the key will be used with
984
985 if ( ( ( flags & ~algorithmFlags ) != 0 ) ||
986 ( ( flags & algorithmFlags ) == 0) )
987 {
988 scError = SYMCRYPT_INVALID_ARGUMENT;
989 goto cleanup;
990 }
991
992 pEckey->fAlgorithmInfo |= flags;
993
994cleanup:
995 return scError;
996}
unsigned char BOOLEAN
Definition: actypes.h:127
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static void cleanup(void)
Definition: main.c:1335
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
VOID SYMCRYPT_CALL SymCryptEckeyFree(_Out_ PSYMCRYPT_ECKEY pkObj)
Definition: eckey.c:35
#define SYMCRYPT_FLAG_ECKEY_PUBLIC_KEY_ORDER_VALIDATION
Definition: eckey.c:176
VOID SYMCRYPT_CALL SymCryptEckeyWipe(_Out_ PSYMCRYPT_ECKEY pkDst)
Definition: eckey.c:115
UINT32 SYMCRYPT_CALL SymCryptEckeySizeofPrivateKey(_In_ PCSYMCRYPT_ECKEY pkEckey)
Definition: eckey.c:164
PSYMCRYPT_ECKEY SYMCRYPT_CALL SymCryptEckeyCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, PCSYMCRYPT_ECURVE pCurve)
Definition: eckey.c:58
UINT32 SYMCRYPT_CALL SymCryptEckeySizeofPublicKey(_In_ PCSYMCRYPT_ECKEY pkEckey, _In_ SYMCRYPT_ECPOINT_FORMAT ecPointFormat)
Definition: eckey.c:147
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEckeyPerformPublicKeyValidation(_In_ PCSYMCRYPT_ECKEY pEckey, _In_ UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: eckey.c:180
#define SYMCRYPT_ECPOINT_SET_RANDOM_MAX_TRIES
Definition: eckey.c:729
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEckeySetRandom(_In_ UINT32 flags, _Inout_ PSYMCRYPT_ECKEY pEckey)
Definition: eckey.c:733
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEckeyExtendKeyUsage(_Inout_ PSYMCRYPT_ECKEY pEckey, UINT32 flags)
Definition: eckey.c:976
VOID SymCryptEckeyCopy(_In_ PCSYMCRYPT_ECKEY pkSrc, _Out_ PSYMCRYPT_ECKEY pkDst)
Definition: eckey.c:122
VOID SYMCRYPT_CALL SymCryptEckeyWipePrivateState(_Inout_ PSYMCRYPT_ECKEY pkEckey)
Definition: eckey.c:106
BOOLEAN SYMCRYPT_CALL SymCryptEckeyHasPrivateKey(_In_ PCSYMCRYPT_ECKEY pkEckey)
Definition: eckey.c:171
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEckeySetValue(_In_reads_bytes_(cbPrivateKey) PCBYTE pbPrivateKey, SIZE_T cbPrivateKey, _In_reads_bytes_(cbPublicKey) PCBYTE pbPublicKey, SIZE_T cbPublicKey, SYMCRYPT_NUMBER_FORMAT numFormat, SYMCRYPT_ECPOINT_FORMAT ecPointFormat, UINT32 flags, _Inout_ PSYMCRYPT_ECKEY pEckey)
Definition: eckey.c:261
PSYMCRYPT_ECKEY SYMCRYPT_CALL SymCryptEckeyAllocate(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: eckey.c:12
UINT32 SYMCRYPT_CALL SymCryptSizeofEckeyFromCurve(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: eckey.c:44
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEckeyGetValue(_In_ PCSYMCRYPT_ECKEY pEckey, _Out_writes_bytes_(cbPrivateKey) PBYTE pbPrivateKey, SIZE_T cbPrivateKey, _Out_writes_bytes_(cbPublicKey) PBYTE pbPublicKey, SIZE_T cbPublicKey, SYMCRYPT_NUMBER_FORMAT numFormat, SYMCRYPT_ECPOINT_FORMAT ecPointFormat, UINT32 flags)
Definition: eckey.c:581
const UINT32 SymCryptEcpointFormatNumberofElements[]
Definition: ecpoint.c:11
GLuint res
Definition: glext.h:9613
GLbitfield flags
Definition: glext.h:7161
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void SYMCRYPT_CALL SymCryptCallbackFree(void *ptr)
Definition: implglue.c:42
void *SYMCRYPT_CALL SymCryptCallbackAlloc(SIZE_T size)
Definition: implglue.c:37
#define _In_reads_bytes_(s)
Definition: no_sal2.h:170
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
BYTE * PBYTE
Definition: pedump.c:66
#define SYMCRYPT_ASSERT_ASYM_ALIGNED(_p)
Definition: sc_lib.h:1912
#define SYMCRYPT_RUN_KEY_GEN_PCT(KeySelftestFunction, Key, KeySelftestFlag)
Definition: sc_lib.h:3699
#define SYMCRYPT_RUN_SELFTEST_ONCE(AlgorithmSelftestFunction, AlgorithmSelftestFlag)
Definition: sc_lib.h:3686
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEcDsaPct(PCSYMCRYPT_ECKEY pkEckey)
UINT32 UINT32 UINT32 UINT32 cbScratch
SIZE_T cbBuffer
Definition: sc_lib_mldsa.h:405
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
UINT32 SYMCRYPT_CALL SymCryptEcurveSizeofScalarMultiplier(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecurve.c:696
#define SYMCRYPT_FLAG_ECKEY_ECDSA
Definition: symcrypt.h:7595
enum _SYMCRYPT_NUMBER_FORMAT SYMCRYPT_NUMBER_FORMAT
@ SYMCRYPT_ECKEY_PRIVATE_FORMAT_DIVH_TIMESH
Definition: symcrypt.h:7132
@ SYMCRYPT_ECKEY_PRIVATE_FORMAT_CANONICAL
Definition: symcrypt.h:7130
enum _SYMCRYPT_ECPOINT_FORMAT SYMCRYPT_ECPOINT_FORMAT
VOID SYMCRYPT_CALL SymCryptEcDsaSelftest(void)
#define SYMCRYPT_FLAG_KEY_NO_FIPS
Definition: symcrypt.h:7579
UINT32 SYMCRYPT_CALL SymCryptEcurveSizeofFieldElement(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecurve.c:689
#define SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION
Definition: symcrypt.h:7586
SYMCRYPT_ERROR
Definition: symcrypt.h:227
VOID SYMCRYPT_CALL SymCryptEcDhSecretAgreementSelftest(void)
#define SYMCRYPT_FLAG_ECKEY_ECDH
Definition: symcrypt.h:7596
@ SYMCRYPT_SELFTEST_ALGORITHM_ECDH
@ SYMCRYPT_SELFTEST_ALGORITHM_ECDSA
#define SYMCRYPT_CALL
const SYMCRYPT_ECKEY * PCSYMCRYPT_ECKEY
SYMCRYPT_MODELEMENT * PSYMCRYPT_MODELEMENT
PCSYMCRYPT_ECURVE pCurve
#define SYMCRYPT_FIPS_ASSERT(x)
SYMCRYPT_MAGIC_FIELD SYMCRYPT_ECKEY
#define SYMCRYPT_SET_MAGIC(p)
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_ECKEY_ECURVE_OPERATIONS(_pCurve)
#define SYMCRYPT_PCT_ECDSA
#define SYMCRYPT_CURVE_IS_MONTGOMERY_TYPE(_pCurve)
SYMCRYPT_ECPOINT * PSYMCRYPT_ECPOINT
const BYTE * PCBYTE
SYMCRYPT_ECKEY * PSYMCRYPT_ECKEY
SYMCRYPT_INT * PSYMCRYPT_INT
const SYMCRYPT_ECURVE * PCSYMCRYPT_ECURVE
#define SYMCRYPT_CHECK_MAGIC(p)
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEcpointSetValue(_In_ PCSYMCRYPT_ECURVE pCurve, _In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc, SYMCRYPT_NUMBER_FORMAT nformat, SYMCRYPT_ECPOINT_FORMAT eformat, _Out_ PSYMCRYPT_ECPOINT poDst, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ecpoint.c:605
UINT32 SYMCRYPT_CALL SymCryptIntIsLessThan(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2)
Definition: a_dispatch.c:442
VOID SYMCRYPT_CALL SymCryptIntToModElement(_In_ PCSYMCRYPT_INT piSrc, _In_ PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:749
VOID SYMCRYPT_CALL SymCryptIntSetBits(_In_ PSYMCRYPT_INT piDst, UINT32 value, UINT32 iBit, UINT32 nBits)
Definition: a_dispatch.c:413
VOID SYMCRYPT_CALL SymCryptIntDivPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T exp, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:364
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEcpointScalarMul(_In_ PCSYMCRYPT_ECURVE pCurve, _In_ PCSYMCRYPT_INT piScalar, _In_opt_ PCSYMCRYPT_ECPOINT poSrc, UINT32 flags, _Out_ PSYMCRYPT_ECPOINT poDst, _Out_writes_bytes_opt_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ec_dispatch.c:262
PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptDivisorFromModulus(_In_ PSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:703
VOID SYMCRYPT_CALL SymCryptIntCopy(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:161
UINT32 SYMCRYPT_CALL SymCryptEcpointIsZero(_In_ PCSYMCRYPT_ECURVE pCurve, _In_ PCSYMCRYPT_ECPOINT poSrc, _Out_writes_bytes_opt_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ec_dispatch.c:176
VOID SYMCRYPT_CALL SymCryptModSetRandom(_In_ PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peDst, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:993
#define SYMCRYPT_FLAG_MODRANDOM_ALLOW_ONE
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptIntSetValue(_In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc, SYMCRYPT_NUMBER_FORMAT format, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:248
PSYMCRYPT_MODELEMENT SYMCRYPT_CALL SymCryptModElementCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, _In_ PCSYMCRYPT_MODULUS pmMod)
Definition: a_dispatch.c:665
VOID SYMCRYPT_CALL SymCryptIntMulPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T exp, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:354
PSYMCRYPT_ECPOINT SYMCRYPT_CALL SymCryptEcpointCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, _In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecpoint.c:142
UINT32 SYMCRYPT_CALL SymCryptEcpointOnCurve(_In_ PCSYMCRYPT_ECURVE pCurve, _In_ PCSYMCRYPT_ECPOINT poSrc, _Out_writes_bytes_opt_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ec_dispatch.c:189
VOID SYMCRYPT_CALL SymCryptModAdd(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc1, _In_ PCSYMCRYPT_MODELEMENT peSrc2, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:838
VOID SYMCRYPT_CALL SymCryptModElementToInt(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_INT piDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:762
VOID SymCryptEcpointCopy(_In_ PCSYMCRYPT_ECURVE pCurve, _In_ PCSYMCRYPT_ECPOINT poSrc, _Out_ PSYMCRYPT_ECPOINT poDst)
Definition: ecpoint.c:173
UINT32 SYMCRYPT_CALL SymCryptSizeofEcpointFromCurve(PCSYMCRYPT_ECURVE pCurve)
Definition: ecpoint.c:41
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntFromModulus(_In_ PSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:720
UINT32 SYMCRYPT_CALL SymCryptEcpointIsEqual(_In_ PCSYMCRYPT_ECURVE pCurve, _In_ PCSYMCRYPT_ECPOINT poSrc1, _In_ PCSYMCRYPT_ECPOINT poSrc2, UINT32 flags, _Out_writes_bytes_opt_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ec_dispatch.c:161
#define SYMCRYPT_FLAG_MODRANDOM_ALLOW_MINUSONE
#define SYMCRYPT_FLAG_ECC_LL_COFACTOR_MUL
UINT32 SYMCRYPT_CALL SymCryptIntIsEqualUint32(_In_ PCSYMCRYPT_INT piSrc1, _In_ UINT32 u32Src2)
Definition: a_dispatch.c:424
UINT32 SYMCRYPT_CALL SymCryptSizeofIntFromDigits(UINT32 nDigits)
Definition: a_dispatch.c:134
UINT32 SYMCRYPT_CALL SymCryptIntGetBits(_In_ PCSYMCRYPT_INT piSrc, UINT32 iBit, UINT32 nBits)
Definition: a_dispatch.c:403
VOID SYMCRYPT_CALL SymCryptIntSetValueUint32(UINT32 u32Src, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:230
UINT32 SYMCRYPT_CALL SymCryptEcurveDigitsofScalarMultiplier(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecurve.c:710
VOID SYMCRYPT_CALL SymCryptIntDivMod(_In_ PCSYMCRYPT_INT piSrc, _In_ PCSYMCRYPT_DIVISOR pdDivisor, _Out_opt_ PSYMCRYPT_INT piQuotient, _Out_opt_ PSYMCRYPT_INT piRemainder, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:573
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptIntGetValue(_In_ PCSYMCRYPT_INT piSrc, _Out_writes_bytes_(cbDst) PBYTE pbDst, SIZE_T cbDst, SYMCRYPT_NUMBER_FORMAT format)
Definition: a_dispatch.c:259
VOID SYMCRYPT_CALL SymCryptModDivPow2(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, UINT32 exp, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:934
#define SYMCRYPT_FLAG_DATA_PUBLIC
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, UINT32 nDigits)
Definition: a_dispatch.c:141
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEcpointGetValue(_In_ PCSYMCRYPT_ECURVE pCurve, _In_ PCSYMCRYPT_ECPOINT poSrc, SYMCRYPT_NUMBER_FORMAT nformat, SYMCRYPT_ECPOINT_FORMAT eformat, _Out_writes_bytes_(cbDst) PBYTE pbDst, SIZE_T cbDst, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ecpoint.c:705
int32_t INT32
Definition: typedefs.h:58
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59