ReactOS 0.4.17-dev-1005-g171e1de
ec_dsa.c
Go to the documentation of this file.
1//
2// ec_dsa.c ECDSA functions
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6//
7
8#include "precomp.h"
9
10/*
11 Sections 7.2.7 and 7.2.8 of the 29 August 2000
12 IEEE Standard Specifications for Public-Key Cryptography,
13 IEEE Std 1363-2000, list DSA versions of the elliptic
14 curve signature and verification primitives.
15 This file has draft interfaces,
16
17 7.2.7 ECSP_DSA (pages 35-36)
18
19 Inputs:
20 E -- An elliptic curve.
21 G (generator) -- A point on E of prime order r.
22 r -- See G.
23 s -- A secret exponent, 1 <= s < r (Private key)
24 msghash -- Hash of the message being signed.
25
26 Outputs:
27 c, d -- Two integers in the interval [1, r-1]
28
29 Algorithm:
30 1) Generate random exponent k, 1 <= k < r,
31 to be kept from adversary.
32 Compute KG = k*G in E.
33 Note KG <> (point at infinity).
34 2) Convert x(KG) (an element of GF(q))
35 to an integer FE2IP(x(KG)).
36 Let c = FE2IP(x(KG)) (mod r).
37 3) Compute d = (msghash + s*c)/k (mod r).
38 4) If c == 0 or d == 0, return to 1).
39 5) Output c and d as integers.
40
41 7.2.8 ECVP_DSA
42
43 Inputs:
44 E, G, r, msghash -- Same as in ECSP_DSA.
45 W -- The signer's public key. Equal to
46 s*G where s was passed to ECSP_DSA.
47 c, d -- A signature to be checked.
48
49 Output:
50 TRUE if signature OK, else FALSE.
51
52 Algorithm:
53 1) If c or d is not in [1, r-1], return FALSE.
54 2) Compute h1 = msghash/d (mod r)
55 and h2 = c/d (mod r).
56 3) Compute P = h1*G + h2*W.
57 If P == (point at infinity), return FALSE.
58 4) If c == FE2IP(x(P)) mod r, return TRUE.
59 Otherwise return FALSE.
60
61FE2IP is a P1363 function that casts a field element to an
62integer (MSB_FIRST). See Section 5.5.5 of P1363.
63*/
64
65//
66// Truncating function according to the standard or
67// the original CNG implementation:
68//
69// Initially both implementations truncate the last **bytes**
70// of the hash that are over the group byte length. Then if
71// the bit length of the hash is still bigger than the bit
72// length of the group order, ...
73//
74// 1. According to the X9.62 standard, we do an appropriate right shift to the entire hash.
75// An example of this is a 160-bit hash, but a 113-bit subgroup order. For this case:
76// a. We would truncate cbHash to (113 + 7) / 8 = 15 bytes.
77// b. Since 15*8 = 120 > 113 we need to right-shift by 7 bits.
78// 2. According to the original CNG implementation, we mask an appropriate number of the
79// topmost bits of the hash.
80// In the same example as before we would zero out the top 7 bits.
81//
86 _In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,
87 SIZE_T cbHashValue,
90 _Out_ PSYMCRYPT_INT piTmp,
93{
94 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
95 UINT32 uiBitsizeOfTmp = 0;
96 UINT32 uiBitsizeOfGroup = 0;
97
98 // Make sure that only the correct flags are set
100 {
101 scError = SYMCRYPT_INVALID_ARGUMENT;
102 goto cleanup;
103 }
104
105 // Get the bitsize of the group order
106 uiBitsizeOfGroup = SymCryptEcurveBitsizeofGroupOrder( pCurve );
107
108 // Truncate the last bytes of the hash
109 if (cbHashValue*8 > uiBitsizeOfGroup)
110 {
111 cbHashValue = (uiBitsizeOfGroup + 7)/8;
112 }
113
114 // Get the value of msghash
115 scError = SymCryptIntSetValue( pbHashValue, cbHashValue, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, piTmp );
116 if ( scError != SYMCRYPT_NO_ERROR )
117 {
118 goto cleanup;
119 }
120
121 // Get the bit size of the hash
122 uiBitsizeOfTmp = (UINT32)cbHashValue * 8;
123
124 // If SYMCRYPT_FLAG_ECDSA_NO_TRUNCATION is set, we don't do hash truncation.
125 // The caller can do their own truncation before calling into Symcrypt.
127 {
128 // ******** Standard truncation **************
129 // Shift right if needed
130 if ( uiBitsizeOfTmp > uiBitsizeOfGroup )
131 {
132 SymCryptIntDivPow2( piTmp, uiBitsizeOfTmp - uiBitsizeOfGroup, piTmp );
133 }
134 }
135
136 SymCryptIntToModElement( piTmp, pCurve->GOrd, peMsghash, pbScratch, cbScratch ); // msghash mod r
137
138cleanup:
139 return scError;
140}
141
142#define SYMCRYPT_MAX_ECDSA_SIGNATURE_COUNT (100)
143
148 _In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,
149 SIZE_T cbHashValue,
153 _Out_writes_bytes_( cbSignature ) PBYTE pbSignature,
154 SIZE_T cbSignature )
155{
156 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
157
158 PBYTE pbScratch = NULL;
159 SIZE_T cbScratch = 0;
160 SIZE_T cbScratchInternal = 0;
161 PBYTE pCurr = NULL;
162
163 PCSYMCRYPT_ECURVE pCurve = pKey->pCurve;
164
165 PSYMCRYPT_INT piTmp = NULL;
166 PSYMCRYPT_INT piMul = NULL;
167 PSYMCRYPT_ECPOINT poKG = NULL;
168
169 PSYMCRYPT_MODELEMENT peMsghash = NULL;
170 PSYMCRYPT_MODELEMENT peSigC = NULL;
171 PSYMCRYPT_MODELEMENT peSigD = NULL;
173
174 PBYTE pbX = NULL;
175
176 UINT32 nDigitsInt = 0;
177 UINT32 nDigitsMul = 0;
178
179 UINT32 cbInt = 0;
180 UINT32 cbMul = 0;
181 UINT32 cbKG = 0;
182 UINT32 cbRs = 0;
183 UINT32 cbX = 0;
184
185 UINT32 signatureCount = 0;
189
190 // Make sure that the key may be used in ECDSA
191 if ( ((pKey->fAlgorithmInfo & SYMCRYPT_FLAG_ECKEY_ECDSA) == 0) )
192 {
193 scError = SYMCRYPT_INVALID_ARGUMENT;
194 goto cleanup;
195 }
196
197 // Make sure only allowed flags are specified and
198 // there is a private key
199 if ( ((flags & ~(allowedFlags)) != 0) ||
200 (!pKey->hasPrivateKey) )
201 {
202 scError = SYMCRYPT_INVALID_ARGUMENT;
203 goto cleanup;
204 }
205
206 // Calculating the digits for the temporary integers
207 nDigitsInt = pCurve->GOrdDigits;
208
210
211 // Objects and scratch space size calculation
212 cbInt = SymCryptSizeofIntFromDigits( nDigitsInt );
213 cbMul = SymCryptSizeofIntFromDigits( nDigitsMul );
217
219 cbScratchInternal = SYMCRYPT_MAX( cbScratchInternal, SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( pCurve->GOrdDigits ) );
220 cbScratchInternal = SYMCRYPT_MAX( cbScratchInternal, SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( pCurve->FModDigits ) );
221 cbScratchInternal = SYMCRYPT_MAX( cbScratchInternal, SYMCRYPT_SCRATCH_BYTES_FOR_MODINV( pCurve->GOrdDigits ) );
222 cbScratchInternal = SYMCRYPT_MAX( cbScratchInternal, SYMCRYPT_SCRATCH_BYTES_FOR_GETSET_VALUE_ECURVE_OPERATIONS( pCurve ) );
223
224 //
225 // From symcrypt_internal.h we have:
226 // - sizeof results are upper bounded by 2^19
227 // - SYMCRYPT_SCRATCH_BYTES results are upper bounded by 2^27 (including RSA and ECURVE)
228 // Thus the following calculation does not overflow cbScratch.
229 //
230 cbScratch = cbScratchInternal + cbInt + cbMul + cbKG + 4*cbRs + cbX;
231
232 // Scratch space allocation
233 pbScratch = SymCryptCallbackAlloc( cbScratch );
234 if ( pbScratch == NULL )
235 {
236 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
237 goto cleanup;
238 }
239
240 // Creating temporaries
241 pCurr = pbScratch + cbScratchInternal;
242 piTmp = SymCryptIntCreate( pCurr, cbInt, nDigitsInt );
243 pCurr += cbInt;
244 piMul = SymCryptIntCreate( pCurr, cbMul, nDigitsMul );
245 pCurr += cbMul;
246 poKG = SymCryptEcpointCreate( pCurr, cbKG, pCurve );
247 pCurr += cbKG;
248 peMsghash = SymCryptModElementCreate( pCurr, cbRs, pCurve->GOrd );
249 pCurr += cbRs;
250 peSigC = SymCryptModElementCreate( pCurr, cbRs, pCurve->GOrd );
251 pCurr += cbRs;
252 peSigD = SymCryptModElementCreate( pCurr, cbRs, pCurve->GOrd );
253 pCurr += cbRs;
254 peTmp = SymCryptModElementCreate( pCurr, cbRs, pCurve->GOrd );
255 pCurr += cbRs;
256 pbX = pCurr;
257
258 SYMCRYPT_ASSERT( piTmp != NULL);
259 SYMCRYPT_ASSERT( piMul != NULL);
260 SYMCRYPT_ASSERT( poKG != NULL);
261 SYMCRYPT_ASSERT( peMsghash != NULL);
262 SYMCRYPT_ASSERT( peSigC != NULL);
263 SYMCRYPT_ASSERT( peSigD != NULL);
264 SYMCRYPT_ASSERT( peTmp != NULL);
265
266 // Truncate the message according to the flags
268 pCurve,
269 pbHashValue,
270 cbHashValue,
271 truncationFlag,
272 peMsghash,
273 piTmp,
274 pbScratch,
275 cbScratchInternal );
276 if ( scError != SYMCRYPT_NO_ERROR )
277 {
278 goto cleanup;
279 }
280
281 //
282 // Main loop: Stop when both c and d are not zero (unless a specific k is provided)
283 //
284 while( TRUE )
285 {
286 if ( piK == NULL )
287 {
288 SymCryptEcpointSetRandom( pCurve, piMul, poKG, pbScratch, cbScratchInternal ); // Generate k and k*G
289 SymCryptIntToModElement( piMul, pCurve->GOrd, peTmp, pbScratch, cbScratchInternal );
290 }
291 else
292 {
293 // Ensure that piK is in the range [1, GOrd-1]
294 if( SymCryptIntIsEqualUint32( piK, 0 ) ||
296 {
297 scError = SYMCRYPT_INVALID_ARGUMENT;
298 goto cleanup;
299 }
300
301 SymCryptIntCopy( piK, piMul );
302 SymCryptIntToModElement( piMul, pCurve->GOrd, peTmp, pbScratch, cbScratchInternal );
303
304 scError = SymCryptEcpointScalarMul( pCurve, piMul, NULL, 0, poKG, pbScratch, cbScratchInternal ); // Generate k*G
305 if ( scError != SYMCRYPT_NO_ERROR )
306 {
307 goto cleanup;
308 }
309 }
310
311 scError = SymCryptModInv( pCurve->GOrd, peTmp, peTmp, publicFlag, pbScratch, cbScratchInternal ); // Invert k
312 if ( scError != SYMCRYPT_NO_ERROR )
313 {
314 goto cleanup;
315 }
316
317 // Get the x coordinates from KG
318 scError = SymCryptEcpointGetValue(
319 pCurve,
320 poKG,
323 pbX,
324 cbX,
325 publicFlag,
326 pbScratch,
327 cbScratchInternal );
328 if ( scError != SYMCRYPT_NO_ERROR )
329 {
330 goto cleanup;
331 }
332
333 // Store c = x(KG) as an integer
334 scError = SymCryptModElementSetValue( pbX, cbX, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pCurve->GOrd, peSigC, pbScratch, cbScratch );
335 if ( scError != SYMCRYPT_NO_ERROR )
336 {
337 goto cleanup;
338 }
339
340 // Move the private key into peSigD
341 SymCryptIntToModElement( pKey->piPrivateKey, pCurve->GOrd, peSigD, pbScratch, cbScratchInternal );
342
343 // Multiply the private key by h since its internal format is "DivH"
344 for (UINT32 i=0; i<pCurve->coFactorPower; i++)
345 {
346 SymCryptModAdd( pCurve->GOrd, peSigD, peSigD, peSigD, pbScratch, cbScratchInternal );
347 }
348
349 SymCryptModMul( pCurve->GOrd, peSigC, peSigD, peSigD, pbScratch, cbScratchInternal ); // s * c
350 SymCryptModAdd( pCurve->GOrd, peMsghash, peSigD, peSigD, pbScratch, cbScratchInternal ); // msghash + s*c
351 SymCryptModMul( pCurve->GOrd, peSigD, peTmp, peSigD, pbScratch, cbScratchInternal ); // ( msghash + s*c ) / k
352
353 if ( !( SymCryptModElementIsZero( pCurve->GOrd, peSigC ) |
354 SymCryptModElementIsZero( pCurve->GOrd, peSigD ) ) )
355 {
356 break;
357 }
358
359 if (piK != NULL)
360 {
361 // piK resulted in 0 signature
362 scError = SYMCRYPT_INVALID_ARGUMENT;
363 goto cleanup;
364 }
365
366 signatureCount++;
367 if ( signatureCount >= SYMCRYPT_MAX_ECDSA_SIGNATURE_COUNT )
368 {
369 // We have not generated a non-zero signature after SYMCRYPT_MAX_ECDSA_SIGNATURE_COUNT attempts;
370 // Something is wrong with the group setup
371 scError = SYMCRYPT_INVALID_ARGUMENT;
372 goto cleanup;
373 }
374 }
375
376 // Output c
377 scError = SymCryptModElementGetValue( pCurve->GOrd, peSigC, pbSignature, cbSignature / 2, format, pbScratch, cbScratchInternal );
378 if ( scError != SYMCRYPT_NO_ERROR )
379 {
380 goto cleanup;
381 }
382
383 // Output d
384 scError = SymCryptModElementGetValue( pCurve->GOrd, peSigD, pbSignature + cbSignature / 2, cbSignature / 2, format, pbScratch, cbScratchInternal );
385 if ( scError != SYMCRYPT_NO_ERROR )
386 {
387 goto cleanup;
388 }
389
390cleanup:
391 if ( pbScratch != NULL )
392 {
393 SymCryptWipe( pbScratch, cbScratch );
394 SymCryptCallbackFree( pbScratch );
395 }
396
397 if (scError != SYMCRYPT_NO_ERROR)
398 {
399 SymCryptWipe( pbSignature, cbSignature );
400 }
401
402 return scError;
403}
404
405
410 _In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,
411 SIZE_T cbHashValue,
414 _Out_writes_bytes_( cbSignature ) PBYTE pbSignature,
415 SIZE_T cbSignature )
416{
417 // Make sure that only the correct flags are set
419 {
420 return SYMCRYPT_INVALID_ARGUMENT;
421 }
422
423 // We must have a private key to perform PCT or signature
424 if( !pKey->hasPrivateKey || !(pKey->fAlgorithmInfo & SYMCRYPT_FLAG_ECKEY_ECDSA) )
425 {
426 return SYMCRYPT_INVALID_ARGUMENT;
427 }
428
429 // If the key was generated in SymCrypt and has not yet had a PCT performed - perform PCT before first use
432 pKey,
434
435 return SymCryptEcDsaSignEx( pKey, pbHashValue, cbHashValue, NULL, format, flags, pbSignature, cbSignature );
436}
437
442 _In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,
443 SIZE_T cbHashValue,
444 _In_reads_bytes_( cbSignature ) PCBYTE pbSignature,
445 SIZE_T cbSignature,
447 UINT32 flags )
448{
449 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
450 PBYTE pbScratch = NULL;
451 SIZE_T cbScratch = 0;
452 SIZE_T cbScratchInternal = 0;
453 PBYTE pCurr = NULL;
454 BOOLEAN fValidSignature = FALSE;
455
456 PCSYMCRYPT_ECURVE pCurve = pKey->pCurve;
457
458 PSYMCRYPT_INT piTmp = NULL;
459 PSYMCRYPT_INT piMul1 = NULL;
460 PSYMCRYPT_INT piMul2 = NULL;
461 PSYMCRYPT_ECPOINT poQ1 = NULL;
462 PSYMCRYPT_ECPOINT poQ2 = NULL;
463
464 PSYMCRYPT_MODELEMENT peMsghash = NULL;
465 PSYMCRYPT_MODELEMENT peSigC = NULL;
466 PSYMCRYPT_MODELEMENT peSigD = NULL;
468
469 PBYTE pbX = NULL;
470 PCSYMCRYPT_ECPOINT poTable[2] = { 0 };
471 PCSYMCRYPT_INT piTable[2] = { 0 };
472
473 UINT32 nDigitsInt = 0;
474 UINT32 nDigitsMul = 0;
475
476 UINT32 cbInt = 0;
477 UINT32 cbMul = 0;
478 UINT32 cbKG = 0;
479 UINT32 cbRs = 0;
480 UINT32 cbX = 0;
481
482 // Make sure that the key may be used in ECDSA
483 if ( ((pKey->fAlgorithmInfo & SYMCRYPT_FLAG_ECKEY_ECDSA) == 0) )
484 {
485 scError = SYMCRYPT_INVALID_ARGUMENT;
486 goto cleanup;
487 }
488
489 // Make sure that only the correct flags are set
491 {
492 scError = SYMCRYPT_INVALID_ARGUMENT;
493 goto cleanup;
494 }
495
496 // Calculating the digits for the temporary integer
497 nDigitsInt = SYMCRYPT_MAX( pCurve->FModDigits, pCurve->GOrdDigits );
498 nDigitsInt = SYMCRYPT_MAX( nDigitsInt, SymCryptDigitsFromBits( (UINT32)cbSignature * 4 ) ); // pbSignature contains (c,d)
499
501
502 // Objects and scratch space size calculation
503 cbInt = SymCryptSizeofIntFromDigits( nDigitsInt );
504 cbMul = SymCryptSizeofIntFromDigits( nDigitsMul );
508
510 cbScratchInternal = SYMCRYPT_MAX( cbScratchInternal, SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( pCurve->GOrdDigits ) );
511 cbScratchInternal = SYMCRYPT_MAX( cbScratchInternal, SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( pCurve->FModDigits ) );
512 cbScratchInternal = SYMCRYPT_MAX( cbScratchInternal, SYMCRYPT_SCRATCH_BYTES_FOR_MODINV( pCurve->GOrdDigits ) );
513 cbScratchInternal = SYMCRYPT_MAX( cbScratchInternal, SYMCRYPT_SCRATCH_BYTES_FOR_GETSET_VALUE_ECURVE_OPERATIONS( pCurve ) );
514 cbScratchInternal = SYMCRYPT_MAX( cbScratchInternal, SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ) );
515
516 //
517 // From symcrypt_internal.h we have:
518 // - sizeof results are upper bounded by 2^19
519 // - SYMCRYPT_SCRATCH_BYTES results are upper bounded by 2^27 (including RSA and ECURVE)
520 // Thus the following calculation does not overflow cbScratch.
521 //
522 cbScratch = cbScratchInternal + cbInt + 2*cbMul + 2*cbKG + 4*cbRs + cbX;
523
524 // Scratch space allocation
525 pbScratch = SymCryptCallbackAlloc( cbScratch );
526 if ( pbScratch == NULL )
527 {
528 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
529 goto cleanup;
530 }
531
532 // Creating temporaries
533 pCurr = pbScratch + cbScratchInternal;
534 piTmp = SymCryptIntCreate( pCurr, cbInt, nDigitsInt );
535 pCurr += cbInt;
536 piMul1 = SymCryptIntCreate( pCurr, cbMul, nDigitsMul );
537 pCurr += cbMul;
538 piMul2 = SymCryptIntCreate( pCurr, cbMul, nDigitsMul );
539 pCurr += cbMul;
540 poQ1 = SymCryptEcpointCreate( pCurr, cbKG, pCurve );
541 pCurr += cbKG;
542 poQ2 = SymCryptEcpointCreate( pCurr, cbKG, pCurve );
543 pCurr += cbKG;
544 peMsghash = SymCryptModElementCreate( pCurr, cbRs, pCurve->GOrd );
545 pCurr += cbRs;
546 peSigC = SymCryptModElementCreate( pCurr, cbRs, pCurve->GOrd );
547 pCurr += cbRs;
548 peSigD = SymCryptModElementCreate( pCurr, cbRs, pCurve->GOrd );
549 pCurr += cbRs;
550 peTmp = SymCryptModElementCreate( pCurr, cbRs, pCurve->GOrd );
551 pCurr += cbRs;
552 pbX = pCurr;
553
554 SYMCRYPT_ASSERT( piTmp != NULL);
555 SYMCRYPT_ASSERT( piMul1 != NULL);
556 SYMCRYPT_ASSERT( piMul2 != NULL);
557 SYMCRYPT_ASSERT( poQ1 != NULL);
558 SYMCRYPT_ASSERT( poQ2 != NULL);
559 SYMCRYPT_ASSERT( peMsghash != NULL);
560 SYMCRYPT_ASSERT( peSigC != NULL);
561 SYMCRYPT_ASSERT( peSigD != NULL);
562 SYMCRYPT_ASSERT( peTmp != NULL);
563
564 // Get c
565 scError = SymCryptIntSetValue( pbSignature, cbSignature / 2, format, piTmp );
566 if ( scError != SYMCRYPT_NO_ERROR )
567 {
568 goto cleanup;
569 }
570
571 // Check if c is less than r
572 if ( !SymCryptIntIsLessThan( piTmp, SymCryptIntFromModulus( pCurve->GOrd ) ) )
573 {
574 goto cleanup;
575 }
576
577 // c mod r
578 SymCryptIntToModElement( piTmp, pCurve->GOrd, peSigC, pbScratch, cbScratchInternal );
579
580 // Check if c is zero
581 if (SymCryptModElementIsZero( pCurve->GOrd, peSigC ))
582 {
583 goto cleanup;
584 }
585
586 // Get d
587 scError = SymCryptIntSetValue( pbSignature + cbSignature / 2, cbSignature / 2, format, piTmp );
588 if ( scError != SYMCRYPT_NO_ERROR )
589 {
590 goto cleanup;
591 }
592
593 // Check if d is less than r
594 if ( !SymCryptIntIsLessThan( piTmp, SymCryptIntFromModulus( pCurve->GOrd ) ) )
595 {
596 goto cleanup;
597 }
598
599 // d mod r
600 SymCryptIntToModElement( piTmp, pCurve->GOrd, peSigD, pbScratch, cbScratchInternal );
601
602 // Check if d is zero
603 if (SymCryptModElementIsZero( pCurve->GOrd, peSigD ))
604 {
605 goto cleanup;
606 }
607
608 // Calculate 1/d mod r
609 // The D value is not secret; it is part of the signature.
610 // We mark it public to avoid the use of random blinding, which would require a source of randomness
611 // just to verify an ECDSA signature.
612 scError = SymCryptModInv( pCurve->GOrd, peSigD, peSigD, SYMCRYPT_FLAG_DATA_PUBLIC, pbScratch, cbScratchInternal );
613 if( scError != SYMCRYPT_NO_ERROR )
614 {
615 goto cleanup;
616 }
617
618 // Truncate the message according to the flags
620 pCurve,
621 pbHashValue,
622 cbHashValue,
623 flags,
624 peMsghash,
625 piTmp,
626 pbScratch,
627 cbScratchInternal );
628 if ( scError != SYMCRYPT_NO_ERROR )
629 {
630 goto cleanup;
631 }
632
633 SymCryptModMul( pCurve->GOrd, peMsghash, peSigD, peMsghash, pbScratch, cbScratchInternal ); // msghash / d = h1
634 SymCryptModMul( pCurve->GOrd, peSigC, peSigD, peTmp, pbScratch, cbScratchInternal ); // c / d = h2
635
636 SymCryptModElementToInt( pCurve->GOrd, peMsghash, piMul1, pbScratch, cbScratchInternal );
637 SymCryptModElementToInt( pCurve->GOrd, peTmp, piMul2, pbScratch, cbScratchInternal );
638
639 // h1*G + h2*W
640 piTable[0] = piMul1;
641 piTable[1] = piMul2;
642
643 poTable[0] = NULL; // The first base point is the generator G of the group
644 poTable[1] = pKey->poPublicKey;
645
646 scError = SymCryptEcpointMultiScalarMul( pCurve, piTable, poTable, 2, SYMCRYPT_FLAG_DATA_PUBLIC, poQ1, pbScratch, cbScratchInternal );
647 if ( scError != SYMCRYPT_NO_ERROR )
648 {
649 goto cleanup;
650 }
651
652 // Check for point at infinity
653 if ( SymCryptEcpointIsZero( pCurve, poQ1, pbScratch, cbScratchInternal ) )
654 {
655 goto cleanup;
656 }
657
658 // Get the x from poQ1
660 if ( scError != SYMCRYPT_NO_ERROR )
661 {
662 goto cleanup;
663 }
664
665 // Store it in a big enough INT
666 scError = SymCryptIntSetValue( pbX, cbX, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, piTmp );
667 if ( scError != SYMCRYPT_NO_ERROR )
668 {
669 goto cleanup;
670 }
671
672 SymCryptIntToModElement( piTmp, pCurve->GOrd, peTmp, pbScratch, cbScratchInternal ); // x mod r
673
674 // Comparison c = x
675 if (SymCryptModElementIsEqual( pCurve->GOrd, peSigC, peTmp ))
676 {
677 fValidSignature = TRUE;
678 }
679
680cleanup:
681
682 if (!fValidSignature)
683 {
684 scError = SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE;
685 }
686
687 if ( pbScratch != NULL )
688 {
689 SymCryptWipe( pbScratch, cbScratch );
690 SymCryptCallbackFree( pbScratch );
691 }
692
693 return scError;
694}
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
#define SYMCRYPT_MAX_ECDSA_SIGNATURE_COUNT
Definition: ec_dsa.c:142
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEcDsaSignEx(_In_ PCSYMCRYPT_ECKEY pKey, _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, _In_opt_ PCSYMCRYPT_INT piK, SYMCRYPT_NUMBER_FORMAT format, UINT32 flags, _Out_writes_bytes_(cbSignature) PBYTE pbSignature, SIZE_T cbSignature)
Definition: ec_dsa.c:146
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEcDsaVerify(_In_ PCSYMCRYPT_ECKEY pKey, _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, _In_reads_bytes_(cbSignature) PCBYTE pbSignature, SIZE_T cbSignature, SYMCRYPT_NUMBER_FORMAT format, UINT32 flags)
Definition: ec_dsa.c:440
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEcDsaSign(_In_ PCSYMCRYPT_ECKEY pKey, _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, SYMCRYPT_NUMBER_FORMAT format, UINT32 flags, _Out_writes_bytes_(cbSignature) PBYTE pbSignature, SIZE_T cbSignature)
Definition: ec_dsa.c:408
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEcDsaTruncateHash(_In_ PCSYMCRYPT_ECURVE pCurve, _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, UINT32 flags, _Out_ PSYMCRYPT_MODELEMENT peMsghash, _Out_ PSYMCRYPT_INT piTmp, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ec_dsa.c:84
GLbitfield flags
Definition: glext.h:7161
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 _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
BYTE * PBYTE
Definition: pedump.c:66
#define SYMCRYPT_RUN_KEY_GEN_PCT(KeySelftestFunction, Key, KeySelftestFlag)
Definition: sc_lib.h:3699
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEcDsaPct(PCSYMCRYPT_ECKEY pkEckey)
UINT32 UINT32 UINT32 UINT32 cbScratch
#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
#define SYMCRYPT_FLAG_ECKEY_ECDSA
Definition: symcrypt.h:7595
UINT32 SYMCRYPT_CALL SymCryptEcurveBitsizeofGroupOrder(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecurve.c:675
enum _SYMCRYPT_NUMBER_FORMAT SYMCRYPT_NUMBER_FORMAT
#define SYMCRYPT_FLAG_ECDSA_NO_TRUNCATION
Definition: symcrypt.h:8327
@ SYMCRYPT_ECPOINT_FORMAT_X
Definition: symcrypt.h:7194
@ SYMCRYPT_NUMBER_FORMAT_MSB_FIRST
Definition: symcrypt.h:7017
UINT32 SYMCRYPT_CALL SymCryptEcurveSizeofFieldElement(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecurve.c:689
SYMCRYPT_ERROR
Definition: symcrypt.h:227
#define SYMCRYPT_CALL
const SYMCRYPT_ECPOINT * PCSYMCRYPT_ECPOINT
const SYMCRYPT_ECKEY * PCSYMCRYPT_ECKEY
SYMCRYPT_MODELEMENT * PSYMCRYPT_MODELEMENT
PCSYMCRYPT_ECURVE pCurve
#define SYMCRYPT_MAX(_a, _b)
PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY pKey
#define SYMCRYPT_PCT_ECDSA
const SYMCRYPT_INT * PCSYMCRYPT_INT
SYMCRYPT_ECPOINT * PSYMCRYPT_ECPOINT
const BYTE * PCBYTE
SYMCRYPT_INT * PSYMCRYPT_INT
const SYMCRYPT_ECURVE * PCSYMCRYPT_ECURVE
UINT32 SYMCRYPT_CALL SymCryptIntIsLessThan(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2)
Definition: a_dispatch.c:442
UINT32 SYMCRYPT_CALL SymCryptSizeofModElementFromModulus(PCSYMCRYPT_MODULUS pmMod)
Definition: a_dispatch.c:658
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
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptEcpointMultiScalarMul(_In_ PCSYMCRYPT_ECURVE pCurve, _In_ PCSYMCRYPT_INT *piSrcScalarArray, _In_ PCSYMCRYPT_ECPOINT *poSrcEcpointArray, UINT32 nPoints, UINT32 flags, _Out_ PSYMCRYPT_ECPOINT poDst, _Out_writes_bytes_opt_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ec_dispatch.c:279
VOID SYMCRYPT_CALL SymCryptIntDivPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T exp, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:364
VOID SYMCRYPT_CALL SymCryptEcpointSetRandom(_In_ PCSYMCRYPT_ECURVE pCurve, _Out_ PSYMCRYPT_INT piScalar, _Out_ PSYMCRYPT_ECPOINT poDst, _Out_writes_bytes_opt_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ec_dispatch.c:147
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
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
UINT32 SYMCRYPT_CALL SymCryptModElementIsZero(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc)
Definition: a_dispatch.c:828
UINT32 SymCryptDigitsFromBits(UINT32 nBits)
Definition: a_dispatch.c:111
UINT32 SYMCRYPT_CALL SymCryptModElementIsEqual(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc1, _In_ PCSYMCRYPT_MODELEMENT peSrc2)
Definition: a_dispatch.c:818
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptModElementSetValue(_In_reads_bytes_(cbSrc) PCBYTE pbSrc, SIZE_T cbSrc, SYMCRYPT_NUMBER_FORMAT format, PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:781
#define SYMCRYPT_SCRATCH_BYTES_FOR_MULTI_SCALAR_ECURVE_OPERATIONS(_pCurve, _nPoints)
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptModElementGetValue(PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_writes_bytes_(cbDst) PBYTE pbDst, SIZE_T cbDst, SYMCRYPT_NUMBER_FORMAT format, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:804
#define SYMCRYPT_SCRATCH_BYTES_FOR_SCALAR_ECURVE_OPERATIONS(_pCurve)
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 SymCryptModMul(_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:867
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptModInv(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_MODELEMENT peDst, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:948
PSYMCRYPT_ECPOINT SYMCRYPT_CALL SymCryptEcpointCreate(_Out_writes_bytes_(cbBuffer) PBYTE pbBuffer, SIZE_T cbBuffer, _In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecpoint.c:142
#define SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS(_nDigits)
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
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
#define SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS(_pCurve)
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 SymCryptEcurveDigitsofScalarMultiplier(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecurve.c:710
#define SYMCRYPT_SCRATCH_BYTES_FOR_GETSET_VALUE_ECURVE_OPERATIONS(_pCurve)
#define SYMCRYPT_FLAG_DATA_PUBLIC
#define SYMCRYPT_SCRATCH_BYTES_FOR_MODINV(_nDigits)
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
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59