ReactOS 0.4.17-dev-1005-g171e1de
dsa.c File Reference
#include "precomp.h"
Include dependency graph for dsa.c:

Go to the source code of this file.

Macros

#define SYMCRYPT_MAX_DSA_SIGNATURE_COUNT   (100)
 

Functions

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptDsaTruncateHash (_In_ PCSYMCRYPT_DLGROUP pDlgroup, _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, UINT32 flags, _Out_ PSYMCRYPT_MODELEMENT peMsghash, _Out_ PSYMCRYPT_INT piIntLarge, _Out_ PSYMCRYPT_INT piIntQ, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptDsaSignEx (_In_ PCSYMCRYPT_DLKEY 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)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptDsaSign (_In_ PCSYMCRYPT_DLKEY 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)
 
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptDsaVerify (_In_ PCSYMCRYPT_DLKEY 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)
 

Macro Definition Documentation

◆ SYMCRYPT_MAX_DSA_SIGNATURE_COUNT

#define SYMCRYPT_MAX_DSA_SIGNATURE_COUNT   (100)

Definition at line 55 of file dsa.c.

Function Documentation

◆ SymCryptDsaSign()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptDsaSign ( _In_ PCSYMCRYPT_DLKEY  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 at line 395 of file dsa.c.

403{
404 return SymCryptDsaSignEx( pKey, pbHashValue, cbHashValue, NULL, format, flags, pbSignature, cbSignature );
405}
#define NULL
Definition: types.h:112
GLbitfield flags
Definition: glext.h:7161
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptDsaSignEx(_In_ PCSYMCRYPT_DLKEY 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: dsa.c:59
PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY pKey

◆ SymCryptDsaSignEx()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptDsaSignEx ( _In_ PCSYMCRYPT_DLKEY  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 at line 59 of file dsa.c.

68{
69 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
70
71 PBYTE pbScratch = NULL;
72 SIZE_T cbScratch = 0;
73 PBYTE pbScratchInternal = NULL;
74 SIZE_T cbScratchInternal = 0;
75
76 SIZE_T cbScratchInputK = 0; // Extra scratch space needed if the caller specified a K
77
79 UINT32 nDigitsOfP = pDlgroup->nDigitsOfP;
80 UINT32 nDigitsOfQ = pDlgroup->nDigitsOfQ;
81
82 UINT32 ndIntLarge = 0;
83
84 UINT32 cbIntLarge = 0;
85 UINT32 cbIntQ = 0;
86 UINT32 cbIntP = 0;
87
88 UINT32 cbModelementP = 0;
89 UINT32 cbModelementQ = 0;
90
91 // Helper Integers
92 PSYMCRYPT_INT piIntLarge = NULL; // Safe size for all caller specified sizes
93 PSYMCRYPT_INT piIntP = NULL; // Same number of digits as P
94 PSYMCRYPT_INT piIntQ = NULL; // Same number of digits as Q
95
96 // Elements modulo P
97 PSYMCRYPT_MODELEMENT peRmodP = NULL;
98
99 // Elements modulo Q
100 PSYMCRYPT_MODELEMENT peMsghash = NULL;
101 PSYMCRYPT_MODELEMENT peRmodQ = NULL;
104
105 UINT32 signatureCount = 0;
106
108
109 // Make sure that the key may be used in DSA
110 if ( ((pKey->fAlgorithmInfo & SYMCRYPT_FLAG_DLKEY_DSA) == 0) )
111 {
112 scError = SYMCRYPT_INVALID_ARGUMENT;
113 goto cleanup;
114 }
115
116 // Make sure that the group and the key have all the
117 // information for dsa, i.e. prime q and private key
118 // modulo q, and we are not using a named DH safe-prime
119 // group
120 if ((!pDlgroup->fHasPrimeQ) ||
121 (!pKey->fHasPrivateKey) ||
122 (!pKey->fPrivateModQ) ||
123 (pDlgroup->isSafePrimeGroup))
124 {
125 scError = SYMCRYPT_INVALID_ARGUMENT;
126 goto cleanup;
127 }
128
129 // Calculate the digit size for the HashValue
130 ndIntLarge = SymCryptDigitsFromBits( (UINT32)cbHashValue * 8 );
131
132 // Calculate the sizes of temp objects
133 cbIntLarge = SymCryptSizeofIntFromDigits(ndIntLarge);
136
139
140 // Allocate scratch space
142
143 //
144 // From symcrypt_internal.h we have:
145 // - sizeof results are upper bounded by 2^19
146 // - SYMCRYPT_SCRATCH_BYTES results are upper bounded by 2^27 (including RSA and ECURVE)
147 // Thus the following calculation does not overflow cbScratch.
148 //
149 cbScratch = cbIntLarge + cbIntQ + cbIntP + cbModelementP + 4*cbModelementQ +
150 SYMCRYPT_MAX( cbScratchInputK,
155 pbScratch = SymCryptCallbackAlloc( cbScratch );
156 if (pbScratch==NULL)
157 {
158 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
159 goto cleanup;
160 }
161
162 // Create the objects
163 pbScratchInternal = pbScratch;
164 cbScratchInternal = cbScratch;
165
166 piIntLarge = SymCryptIntCreate(pbScratchInternal, cbIntLarge, ndIntLarge); pbScratchInternal += cbIntLarge; cbScratchInternal -= cbIntLarge;
167 piIntQ = SymCryptIntCreate(pbScratchInternal, cbIntQ, nDigitsOfQ); pbScratchInternal += cbIntQ; cbScratchInternal -= cbIntQ;
168 piIntP = SymCryptIntCreate(pbScratchInternal, cbIntP, nDigitsOfP); pbScratchInternal += cbIntP; cbScratchInternal -= cbIntP;
169
170 peRmodP = SymCryptModElementCreate(pbScratchInternal, cbModelementP, pDlgroup->pmP); pbScratchInternal += cbModelementP; cbScratchInternal -= cbModelementP;
171
172 peMsghash = SymCryptModElementCreate(pbScratchInternal, cbModelementQ, pDlgroup->pmQ); pbScratchInternal += cbModelementQ; cbScratchInternal -= cbModelementQ;
173 peRmodQ = SymCryptModElementCreate(pbScratchInternal, cbModelementQ, pDlgroup->pmQ); pbScratchInternal += cbModelementQ; cbScratchInternal -= cbModelementQ;
174 peK = SymCryptModElementCreate(pbScratchInternal, cbModelementQ, pDlgroup->pmQ); pbScratchInternal += cbModelementQ; cbScratchInternal -= cbModelementQ;
175 peS = SymCryptModElementCreate(pbScratchInternal, cbModelementQ, pDlgroup->pmQ); pbScratchInternal += cbModelementQ; cbScratchInternal -= cbModelementQ;
176
177 // Get the message into a modelement
178 scError = SymCryptDsaTruncateHash(
179 pDlgroup,
180 pbHashValue,
181 cbHashValue,
182 flags,
183 peMsghash,
184 piIntLarge,
185 piIntQ,
186 pbScratchInternal,
187 cbScratchInternal );
188 if (scError!=SYMCRYPT_NO_ERROR)
189 {
190 goto cleanup;
191 }
192
193 //
194 // Main loop: Stop when both R and S are not zero (unless a specific k is provided)
195 //
196 while( TRUE )
197 {
198 if (piK==NULL)
199 {
201 pDlgroup->pmQ,
202 peK,
204 pbScratchInternal,
205 cbScratchInternal );
206
208 pDlgroup->pmQ,
209 peK,
210 piIntQ,
211 pbScratchInternal,
212 cbScratchInternal );
213 }
214 else
215 {
217 piK,
219 NULL,
220 piIntQ,
221 pbScratchInternal,
222 cbScratchInternal );
223
225 piIntQ,
226 pDlgroup->pmQ,
227 peK,
228 pbScratchInternal,
229 cbScratchInternal );
230
231 // Make sure that the K passed in is not zero
232 if (SymCryptModElementIsZero(pDlgroup->pmQ, peK))
233 {
234 scError = SYMCRYPT_INVALID_ARGUMENT;
235 goto cleanup;
236 }
237 }
238
239 // Here piIntQ and peK hold the random exponent K
240
241 // G^K mod P
243 pDlgroup->pmP,
244 pDlgroup->peG,
245 piIntQ,
246 pDlgroup->nBitsOfQ,
247 0, // Side-channel safe
248 peRmodP,
249 pbScratchInternal,
250 cbScratchInternal );
251
252 // Convert to integer
254 pDlgroup->pmP,
255 peRmodP,
256 piIntP,
257 pbScratchInternal,
258 cbScratchInternal );
259
260 // Convert to mod Q
262 piIntP,
264 NULL,
265 piIntQ,
266 pbScratchInternal,
267 cbScratchInternal );
268
269 // Convert to modelement
271 piIntQ,
272 pDlgroup->pmQ,
273 peRmodQ,
274 pbScratchInternal,
275 cbScratchInternal );
276
277 // Invert k mod q
278 scError = SymCryptModInv(
279 pDlgroup->pmQ,
280 peK,
281 peK, // In place
282 0,
283 pbScratchInternal,
284 cbScratchInternal );
285 if( scError != SYMCRYPT_NO_ERROR )
286 {
287 goto cleanup;
288 }
289
290 // Get the private key X to modelement
291 // *** We are sure here that the digit
292 // size of it is nDigitsOfQ
294 pKey->piPrivateKey,
295 pDlgroup->pmQ,
296 peS,
297 pbScratchInternal,
298 cbScratchInternal );
299
300 // X*R
302 pDlgroup->pmQ,
303 peS,
304 peRmodQ,
305 peS,
306 pbScratchInternal,
307 cbScratchInternal );
308
309 // H(m)+X*R
311 pDlgroup->pmQ,
312 peS,
313 peMsghash,
314 peS,
315 pbScratchInternal,
316 cbScratchInternal );
317
318 // S = k^{-1}*(H(m)+X*R)
320 pDlgroup->pmQ,
321 peK,
322 peS,
323 peS,
324 pbScratchInternal,
325 cbScratchInternal );
326
327 if ( !( SymCryptModElementIsZero( pDlgroup->pmQ, peRmodQ ) |
328 SymCryptModElementIsZero( pDlgroup->pmQ, peS ) ) )
329 {
330 break;
331 }
332
333 if (piK != NULL)
334 {
335 // piK resulted in 0 signature
336 scError = SYMCRYPT_INVALID_ARGUMENT;
337 goto cleanup;
338 }
339
340 signatureCount++;
341 if ( signatureCount >= SYMCRYPT_MAX_DSA_SIGNATURE_COUNT )
342 {
343 // We have not generated a non-zero signature after SYMCRYPT_MAX_DSA_SIGNATURE_COUNT attempts;
344 // Something is wrong with the group setup
345 scError = SYMCRYPT_INVALID_ARGUMENT;
346 goto cleanup;
347 }
348 }
349
350 // Output R
352 pDlgroup->pmQ,
353 peRmodQ,
354 pbSignature,
355 cbSignature / 2,
356 format,
357 pbScratchInternal,
358 cbScratchInternal );
359 if ( scError != SYMCRYPT_NO_ERROR )
360 {
361 goto cleanup;
362 }
363
364 // Output S
366 pDlgroup->pmQ,
367 peS,
368 pbSignature + cbSignature / 2,
369 cbSignature / 2,
370 format,
371 pbScratchInternal,
372 cbScratchInternal );
373 if ( scError != SYMCRYPT_NO_ERROR )
374 {
375 goto cleanup;
376 }
377
378cleanup:
379 if ( pbScratch != NULL )
380 {
381 SymCryptWipe( pbScratch, cbScratch );
382 SymCryptCallbackFree( pbScratch );
383 }
384
385 if (scError != SYMCRYPT_NO_ERROR)
386 {
387 SymCryptWipe( pbSignature, cbSignature );
388 }
389
390 return scError;
391}
#define TRUE
Definition: types.h:120
static void cleanup(void)
Definition: main.c:1335
void SYMCRYPT_CALL SymCryptCallbackFree(void *ptr)
Definition: implglue.c:42
void *SYMCRYPT_CALL SymCryptCallbackAlloc(SIZE_T size)
Definition: implglue.c:37
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
BYTE * PBYTE
Definition: pedump.c:66
UINT32 UINT32 UINT32 UINT32 cbScratch
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptDsaTruncateHash(_In_ PCSYMCRYPT_DLGROUP pDlgroup, _In_reads_bytes_(cbHashValue) PCBYTE pbHashValue, SIZE_T cbHashValue, UINT32 flags, _Out_ PSYMCRYPT_MODELEMENT peMsghash, _Out_ PSYMCRYPT_INT piIntLarge, _Out_ PSYMCRYPT_INT piIntQ, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: dsa.c:13
#define SYMCRYPT_MAX_DSA_SIGNATURE_COUNT
Definition: dsa.c:55
#define SYMCRYPT_FLAG_DLKEY_DSA
Definition: symcrypt.h:7592
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
SYMCRYPT_ERROR
Definition: symcrypt.h:227
PCSYMCRYPT_DLGROUP pDlgroup
SYMCRYPT_MODELEMENT * PSYMCRYPT_MODELEMENT
#define SYMCRYPT_MAX(_a, _b)
PSYMCRYPT_MODULUS pmQ
UINT32 nDigitsOfQ
PSYMCRYPT_MODULUS pmP
SYMCRYPT_INT * PSYMCRYPT_INT
UINT32 nDigitsOfP
const SYMCRYPT_DLGROUP * PCSYMCRYPT_DLGROUP
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
PSYMCRYPT_DIVISOR SYMCRYPT_CALL SymCryptDivisorFromModulus(_In_ PSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:703
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
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_DIVMOD(_nSrcDigits, _nDivisorDigits)
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
UINT32 SYMCRYPT_CALL SymCryptIntDigitsizeOfObject(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:207
#define SYMCRYPT_FLAG_MODRANDOM_ALLOW_ONE
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
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
#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
#define SYMCRYPT_FLAG_MODRANDOM_ALLOW_MINUSONE
UINT32 SYMCRYPT_CALL SymCryptSizeofIntFromDigits(UINT32 nDigits)
Definition: a_dispatch.c:134
VOID SYMCRYPT_CALL SymCryptModExp(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peBase, _In_ PCSYMCRYPT_INT piExp, UINT32 nBitsExp, UINT32 flags, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:961
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
#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
#define SYMCRYPT_SCRATCH_BYTES_FOR_MODEXP(_nDigits)
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59

Referenced by SymCryptDsaSign().

◆ SymCryptDsaTruncateHash()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptDsaTruncateHash ( _In_ PCSYMCRYPT_DLGROUP  pDlgroup,
_In_reads_bytes_(cbHashValue) PCBYTE  pbHashValue,
SIZE_T  cbHashValue,
UINT32  flags,
_Out_ PSYMCRYPT_MODELEMENT  peMsghash,
_Out_ PSYMCRYPT_INT  piIntLarge,
_Out_ PSYMCRYPT_INT  piIntQ,
_Out_writes_bytes_(cbScratch) PBYTE  pbScratch,
SIZE_T  cbScratch 
)

Definition at line 13 of file dsa.c.

23{
24 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
25
27
28 // Get the value of msghash into piIntLarge
29 scError = SymCryptIntSetValue( pbHashValue, cbHashValue, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, piIntLarge );
30 if ( scError != SYMCRYPT_NO_ERROR )
31 {
32 goto cleanup;
33 }
34
35 // Truncate the rightmost bits if the value exceeds the size of the modulus Q
36 if (SymCryptIntBitsizeOfValue(piIntLarge) > pDlgroup->nBitsOfQ)
37 {
38 SymCryptIntDivPow2( piIntLarge, SymCryptIntBitsizeOfValue(piIntLarge) - pDlgroup->nBitsOfQ, piIntLarge );
39 }
40
41 scError = SymCryptIntCopyMixedSize( piIntLarge, piIntQ );
42 if ( scError != SYMCRYPT_NO_ERROR )
43 {
44 // This should never fail here as we truncated the IntLarge
45 goto cleanup;
46 }
47
48 // Now we can call IntToModElement as they have the same digit size
49 SymCryptIntToModElement( piIntQ, pDlgroup->pmQ, peMsghash, pbScratch, cbScratch ); // msghash mod Q
50
52 return scError;
53}
@ SYMCRYPT_NUMBER_FORMAT_MSB_FIRST
Definition: symcrypt.h:7017
VOID SYMCRYPT_CALL SymCryptIntDivPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T exp, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:364
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptIntCopyMixedSize(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:214
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
UINT32 SYMCRYPT_CALL SymCryptIntBitsizeOfValue(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:223

Referenced by SymCryptDsaSignEx(), and SymCryptDsaVerify().

◆ SymCryptDsaVerify()

SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptDsaVerify ( _In_ PCSYMCRYPT_DLKEY  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 at line 410 of file dsa.c.

418{
419 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
420 BOOLEAN fValidSignature = FALSE;
421
422 PBYTE pbScratch = NULL;
423 SIZE_T cbScratch = 0;
424 PBYTE pbScratchInternal = NULL;
425 SIZE_T cbScratchInternal = 0;
426
427 PCSYMCRYPT_DLGROUP pDlgroup = pKey->pDlgroup;
428 UINT32 nDigitsOfP = pDlgroup->nDigitsOfP;
429 UINT32 nDigitsOfQ = pDlgroup->nDigitsOfQ;
430
431 UINT32 ndIntLarge = 0;
432
433 UINT32 cbIntLarge = 0;
434 UINT32 cbIntQ = 0;
435 UINT32 cbIntP = 0;
436
437 UINT32 cbModelementP = 0;
438 UINT32 cbModelementQ = 0;
439
440 PSYMCRYPT_MODELEMENT peBases[2] = { NULL, NULL }; // Array with pointers to base points
441
442 // Helper Integers
443 PSYMCRYPT_INT piIntLarge = NULL; // Safe size for all caller specified sizes
444 PSYMCRYPT_INT piIntP = NULL; // Same number of digits as P
445 PSYMCRYPT_INT piIntQ[2] = { NULL, NULL }; // Same number of digits as Q
446
447 // Elements modulo P
448 PSYMCRYPT_MODELEMENT peResP = NULL;
449
450 // Elements modulo Q
453 PSYMCRYPT_MODELEMENT peT = NULL; // Temp
454
456
457 // Make sure that the key may be used in DSA
458 if ( ((pKey->fAlgorithmInfo & SYMCRYPT_FLAG_DLKEY_DSA) == 0) )
459 {
460 scError = SYMCRYPT_INVALID_ARGUMENT;
461 goto cleanup;
462 }
463
464 // Make sure that the group has a prime q, and we are not using a named DH safe-prime group
465 if (!pDlgroup->fHasPrimeQ || pDlgroup->isSafePrimeGroup)
466 {
467 scError = SYMCRYPT_INVALID_ARGUMENT;
468 goto cleanup;
469 }
470
471 // Calculate the digit sizes
472 ndIntLarge = SymCryptDigitsFromBits( (UINT32)cbHashValue * 8 );
473 ndIntLarge = SYMCRYPT_MAX( ndIntLarge, SymCryptDigitsFromBits( (UINT32)cbSignature * 4 ) ); // pbSignature contains (R,S)
474
475 // Calculate the sizes of temp objects
476 cbIntLarge = SymCryptSizeofIntFromDigits(ndIntLarge);
479
482
483 //
484 // From symcrypt_internal.h we have:
485 // - sizeof results are upper bounded by 2^19
486 // - SYMCRYPT_SCRATCH_BYTES results are upper bounded by 2^27 (including RSA and ECURVE)
487 // Thus the following calculation does not overflow cbScratch.
488 //
489 cbScratch = cbIntLarge + cbIntP + 2*cbIntQ + cbModelementP + 3*cbModelementQ +
495 pbScratch = SymCryptCallbackAlloc( cbScratch );
496 if (pbScratch==NULL)
497 {
498 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
499 goto cleanup;
500 }
501
502 // Create the objects
503 pbScratchInternal = pbScratch;
504 cbScratchInternal = cbScratch;
505
506 piIntLarge = SymCryptIntCreate(pbScratchInternal, cbIntLarge, ndIntLarge); pbScratchInternal += cbIntLarge; cbScratchInternal -= cbIntLarge;
507 piIntP = SymCryptIntCreate(pbScratchInternal, cbIntP, nDigitsOfP); pbScratchInternal += cbIntP; cbScratchInternal -= cbIntP;
508 piIntQ[0] = SymCryptIntCreate(pbScratchInternal, cbIntQ, nDigitsOfQ); pbScratchInternal += cbIntQ; cbScratchInternal -= cbIntQ;
509 piIntQ[1] = SymCryptIntCreate(pbScratchInternal, cbIntQ, nDigitsOfQ); pbScratchInternal += cbIntQ; cbScratchInternal -= cbIntQ;
510
511 peResP = SymCryptModElementCreate(pbScratchInternal, cbModelementP, pDlgroup->pmP); pbScratchInternal += cbModelementP; cbScratchInternal -= cbModelementP;
512
513 peR = SymCryptModElementCreate(pbScratchInternal, cbModelementQ, pDlgroup->pmQ); pbScratchInternal += cbModelementQ; cbScratchInternal -= cbModelementQ;
514 peS = SymCryptModElementCreate(pbScratchInternal, cbModelementQ, pDlgroup->pmQ); pbScratchInternal += cbModelementQ; cbScratchInternal -= cbModelementQ;
515 peT = SymCryptModElementCreate(pbScratchInternal, cbModelementQ, pDlgroup->pmQ); pbScratchInternal += cbModelementQ; cbScratchInternal -= cbModelementQ;
516
517 // Get R
518 scError = SymCryptIntSetValue( pbSignature, cbSignature / 2, format, piIntLarge );
519 if ( scError != SYMCRYPT_NO_ERROR )
520 {
521 goto cleanup;
522 }
523
524 // Check if R is less than Q
525 if ( !SymCryptIntIsLessThan( piIntLarge, SymCryptIntFromModulus( pDlgroup->pmQ ) ) )
526 {
527 goto cleanup;
528 }
529
530 // R mod Q (use piIntQ[0] as temp space)
531 scError = SymCryptIntCopyMixedSize( piIntLarge, piIntQ[0] );
532 if ( scError != SYMCRYPT_NO_ERROR )
533 {
534 // This should never fail here as we verified that IntLarge is less than Q
535 goto cleanup;
536 }
537 SymCryptIntToModElement( piIntQ[0], pDlgroup->pmQ, peR, pbScratchInternal, cbScratchInternal );
538
539 // Check if R is zero
540 if (SymCryptModElementIsZero( pDlgroup->pmQ, peR ))
541 {
542 goto cleanup;
543 }
544
545 // Get S
546 scError = SymCryptIntSetValue( pbSignature + cbSignature / 2, cbSignature / 2, format, piIntLarge );
547 if ( scError != SYMCRYPT_NO_ERROR )
548 {
549 goto cleanup;
550 }
551
552 // Check if S is less than Q
553 if ( !SymCryptIntIsLessThan( piIntLarge, SymCryptIntFromModulus( pDlgroup->pmQ ) ) )
554 {
555 goto cleanup;
556 }
557
558 // S mod Q (use piIntQ[0] as temp space)
559 scError = SymCryptIntCopyMixedSize( piIntLarge, piIntQ[0] );
560 if ( scError != SYMCRYPT_NO_ERROR )
561 {
562 // This should never fail here as we verified that IntLarge is less than Q
563 goto cleanup;
564 }
565 SymCryptIntToModElement( piIntQ[0], pDlgroup->pmQ, peS, pbScratchInternal, cbScratchInternal );
566
567 // Check if S is zero
568 if (SymCryptModElementIsZero( pDlgroup->pmQ, peS ))
569 {
570 goto cleanup;
571 }
572
573 // Calculate 1/S mod Q
574 // S is part of the signature and therefore not a secret.
575 // We mark it public to avoid the use of random blinding, which would require a source of randomness
576 // just to verify a DSA signature.
577 scError = SymCryptModInv( pDlgroup->pmQ, peS, peS, SYMCRYPT_FLAG_DATA_PUBLIC, pbScratchInternal, cbScratchInternal );
578 if( scError != SYMCRYPT_NO_ERROR )
579 {
580 goto cleanup;
581 }
582
583 // Get the message into a modelement
584 scError = SymCryptDsaTruncateHash(
585 pDlgroup,
586 pbHashValue,
587 cbHashValue,
588 flags,
589 peT,
590 piIntLarge,
591 piIntQ[0],
592 pbScratchInternal,
593 cbScratchInternal );
594 if (scError!=SYMCRYPT_NO_ERROR)
595 {
596 goto cleanup;
597 }
598
599 // Calculate U1 = Hash(M)/S modQ
601 pDlgroup->pmQ,
602 peT,
603 peS,
604 peT,
605 pbScratchInternal,
606 cbScratchInternal );
607
608 // Convert U1 to integer
610 pDlgroup->pmQ,
611 peT,
612 piIntQ[0],
613 pbScratchInternal,
614 cbScratchInternal );
615
616 // Calculate U2 = R/S modQ
618 pDlgroup->pmQ,
619 peR,
620 peS,
621 peT,
622 pbScratchInternal,
623 cbScratchInternal );
624
625 // Convert U2 to integer
627 pDlgroup->pmQ,
628 peT,
629 piIntQ[1],
630 pbScratchInternal,
631 cbScratchInternal );
632
633 // Arrange the pointers for v = G^U1 * Y^U2
634 peBases[0] = pDlgroup->peG;
635 peBases[1] = pKey->pePublicKey;
636
637 // v = G^U1 * Y^U2
638 scError = SymCryptModMultiExp(
639 pDlgroup->pmP,
640 peBases,
641 piIntQ,
642 2,
643 pDlgroup->nBitsOfQ,
645 peResP,
646 pbScratchInternal,
647 cbScratchInternal );
648 if (scError!=SYMCRYPT_NO_ERROR)
649 {
650 goto cleanup;
651 }
652
653 // Convert V to a modelement modulo Q
655 pDlgroup->pmP,
656 peResP,
657 piIntP,
658 pbScratchInternal,
659 cbScratchInternal );
661 piIntP,
663 NULL,
664 piIntQ[0],
665 pbScratchInternal,
666 cbScratchInternal );
668 piIntQ[0],
669 pDlgroup->pmQ,
670 peT,
671 pbScratchInternal,
672 cbScratchInternal );
673
674 // Comparison V = R
675 if (SymCryptModElementIsEqual( pDlgroup->pmQ, peT, peR ))
676 {
677 fValidSignature = TRUE;
678 }
679
680
681cleanup:
682
683 if (!fValidSignature)
684 {
685 scError = SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE;
686 }
687
688 if ( pbScratch != NULL )
689 {
690 SymCryptWipe( pbScratch, cbScratch );
691 SymCryptCallbackFree( pbScratch );
692 }
693
694 return scError;
695}
unsigned char BOOLEAN
Definition: actypes.h:127
#define FALSE
Definition: types.h:117
UINT32 SYMCRYPT_CALL SymCryptIntIsLessThan(_In_ PCSYMCRYPT_INT piSrc1, _In_ PCSYMCRYPT_INT piSrc2)
Definition: a_dispatch.c:442
#define SYMCRYPT_SCRATCH_BYTES_FOR_MODMULTIEXP(_nDigits, _nBases, _nBitsExp)
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 SymCryptModMultiExp(_In_ PCSYMCRYPT_MODULUS pmMod, _In_reads_(nBases) PCSYMCRYPT_MODELEMENT *peBaseArray, _In_reads_(nBases) PCSYMCRYPT_INT *piExpArray, UINT32 nBases, UINT32 nBitsExp, UINT32 flags, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:976
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntFromModulus(_In_ PSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:720
UINT32 SYMCRYPT_CALL SymCryptModulusDigitsizeOfObject(_In_ PCSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:635
#define SYMCRYPT_FLAG_DATA_PUBLIC