ReactOS 0.4.17-dev-1005-g171e1de
IEEE802_11SaeCustom.c
Go to the documentation of this file.
1//
2// IEEE802_11SaeCustom.c Implementation of the custom crypto of IEEE 802.11 SAE
3//
4// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5//
6//
7
8#include "precomp.h"
9
10// Used in SAE Hunting and Pecking methods where NIST P256 is hardcoded
11#define PRIME_LENGTH_BITS 256
12
13//
14// This data structure is used to store the associated elliptic curve and the z value corresponding to
15// each IANA group mappings for each elliptic
16// curve defined in IEEE Std 802.11 SAE method.
17//
24
26
27//
28// Data based on IEEE Std 802.11-2020
29// Table 12.1 - Hash algorithm based on length of prime
30// Table 12.2 - Unique curve parameter
31//
35};
36
37//
38// Helper function that finds the associated IANA group data entry for a given group number
39// Searches the global variable g_ianaData where the data for supported groups are stored
40//
42{
44 {
45 if ( g_ianaData[index].group == ianaGroup )
46 {
47 return &g_ianaData[index];
48 }
49 }
50
51 return NULL;
52}
53
54//
55// Helper function that returns the sizes of the field elements and elliptic curve points in bytes
56// for a given IANA group number. Both output parameters are optional.
57//
60 _Out_opt_ SIZE_T* pcbScalar,
61 _Out_opt_ SIZE_T* pcbPoint )
62{
64 SIZE_T cbScalar = 0;
65 SIZE_T cbPoint = 0;
66
67 pGroupData = SymCryptSaeFindGroupData( group );
68
69 if ( pGroupData != NULL )
70 {
71 cbScalar = ( *( pGroupData->pCurveParams ) )->cbFieldLength;
72 cbPoint = 2 * cbScalar;
73 }
74
75 if ( pcbScalar != NULL )
76 {
77 *pcbScalar = cbScalar;
78 }
79
80 if ( pcbPoint != NULL )
81 {
82 *pcbPoint = cbPoint;
83 }
84}
85
86//
87// Calculate sqrt(peVal) if it exists. If so, *puIsQuadraticResidue is set to 0xFFFF`FFFF.
88// Otherwise, *puIsQuadraticResidue is set to 0.
89// WARNING: *peSqrtArg is set even if the square root doesn't exist. Use masked copy functions
90// with *puIsQuadraticResidue so as to use the value of *peSqrtArg only if the square root exists.
91//
92// - pmMod: Modulus of the curve. Must equal 3 mod 4, which holds for all NIST Prime curves except P224
93// - peVal: Value to calculate the square root of
94// - puIsQuadraticResidue: mask value, true if sqrt(peVal) exists, false otherwise
95// - peSqrtArg: optional out argument for square root value
96// - pbScratch, cbScratch: scratch space >= SYMCRYPT_SCRATCH_BYTES_FOR_MODEXP( pmMod->nDigits )
97//
102 _Out_ PUINT32 puIsQuadraticResidue,
106{
107 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
108
109 PSYMCRYPT_INT piTmp = SymCryptIntAllocate( SymCryptDigitsFromBits( pmMod->Divisor.nBits ) );
112
113 if( piTmp == NULL || peSqrt == NULL || peTmp == NULL )
114 {
115 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
116 goto cleanup;
117 }
118
119 // Sqrt( v ) = v^{(P+1)/4} mod P when P = 3 mod 4 as it is here
120 SymCryptIntCopy( SymCryptIntFromModulus( pmMod ), piTmp );
121 SymCryptIntAddUint32( piTmp, 1, piTmp ); // No overflow as our prime is not 2^256 - 1
122
124 SymCryptIntDivPow2(piTmp, 2, piTmp);
125 // iX = (P+1)/4
126
127 // Compute Sqrt( v ) if it exists
128 SymCryptModExp( pmMod, peVal, piTmp, pmMod->Divisor.nBits - 2, 0, peSqrt, pbScratch, cbScratch );
129
130 SymCryptModSquare( pmMod, peSqrt, peTmp, pbScratch, cbScratch );
131 *puIsQuadraticResidue = SymCryptModElementIsEqual( pmMod, peTmp, peVal );
132
133 if( peSqrtArg != NULL )
134 {
135 SymCryptModElementCopy( pmMod, peSqrt, peSqrtArg );
136 }
137
138cleanup:
139
140 if( piTmp != NULL )
141 {
142 SymCryptIntFree( piTmp );
143 piTmp = NULL;
144 }
145
146 if( peSqrt != NULL )
147 {
148 SymCryptModElementFree( pmMod, peSqrt );
149 peSqrt = NULL;
150 }
151
152 if( peTmp != NULL )
153 {
154 SymCryptModElementFree( pmMod, peTmp );
155 peTmp = NULL;
156 }
157
158 return scError;
159
160}
161
162//
163// Calculates SSWU( u ) as described in 12.4.4.2.3
164//
165// - pCurve: The curve object to use.
166// - z: z value used in the SSWU calculation. Currently we assume this value to be negative.
167// - peU: Value to calculate SSWU of.
168// - popP: point on the curve found by SSWU.
169// - pbScratch, cbScratch: scratch space >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve )
170//
174 _In_ INT32 z,
179{
180 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
181
182 UINT32 selectionMask = 0; // Mask variable for masked copy operations. "l" in the spec
183
184 PSYMCRYPT_INT piTmp = NULL;
186
194
196
197 SYMCRYPT_ASSERT( z < 0 );
198
199 piTmp = SymCryptIntAllocate( SymCryptDigitsFromBits( pCurve->FModBitsize ) );
200
201 peTmp = SymCryptModElementAllocate( pCurve->FMod );
202 peZ = SymCryptModElementAllocate( pCurve->FMod );
203 peM = SymCryptModElementAllocate( pCurve->FMod );
204 peT = SymCryptModElementAllocate( pCurve->FMod );
205 peX1 = SymCryptModElementAllocate( pCurve->FMod );
206 peX2 = SymCryptModElementAllocate( pCurve->FMod );
207 peGX1 = SymCryptModElementAllocate( pCurve->FMod );
208 peGX2 = SymCryptModElementAllocate( pCurve->FMod );
209
210 if( piTmp == NULL|| peTmp == NULL || peZ == NULL || peM == NULL || peT == NULL ||
211 peX1 == NULL || peX2 == NULL || peGX1 == NULL || peGX2 == NULL)
212 {
213 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
214 goto cleanup;
215 }
216
217 // Convert z to mod element
218 // Currently we avoid a branching based on the sign of z to make the assignment and assume it will
219 // be negative which holds for the set of possible values as of now (NIST P256 and NIST P384).
220 // There is no direct function to create a SYMCRYPT_INT from a signed INT32, so when z is negative
221 // we change its sign and call SymCryptModElementSetValueNegUInt32
222 SymCryptModElementSetValueNegUint32(-z, pCurve->FMod, peZ, pbScratch, cbScratch);
223
224 // Set peTmp to 1 for convenience later
225 SymCryptModElementSetValueUint32( 1, pCurve->FMod, peTmp, pbScratch, cbScratch );
226
227 // m = ( z^2 * u^4 + z * u^2 ) = (z * u^2)(z * u^2 + 1) modulo p
228 SymCryptModSquare( pCurve->FMod, peU, peM, pbScratch, cbScratch ); // M = u^2
229 SymCryptModMul( pCurve->FMod, peM, peZ, peM, pbScratch, cbScratch ); // M = z * u^2
230 SymCryptModAdd( pCurve->FMod, peM, peTmp, peTmp, pbScratch, cbScratch ); // tmp = (z * u^2 + 1)
231 SymCryptModMul( pCurve->FMod, peM, peTmp, peM, pbScratch, cbScratch ); // M = M * tmp = (z * u^2)(z * u^2 + 1)
232
233 // l = CEQ( m, 0 )
234 selectionMask = SymCryptModElementIsZero( pCurve->FMod, peM );
235
236 // t = inverse( m ) where inverse ( m ) = m^( p-2 ) modulo p
238 SymCryptModExp( pCurve->FMod, peM, piTmp, pCurve->FModBitsize, 0, peT, pbScratch, cbScratch );
239
240 //x1 = CSEL( l, ( b / ( z * a ) modulo p ), ( ( - b / a ) * ( 1 + t ) ) modulo p )
241 // where CSEL(x,y,z) operates in constant time and returns y if x is true and z otherwise.
242 SymCryptModMul( pCurve->FMod, peZ, pCurve->A, peTmp, pbScratch, cbScratch ); // tmp = z * a
243 SymCryptModInv( pCurve->FMod, peTmp, peTmp, SYMCRYPT_FLAG_DATA_PUBLIC | SYMCRYPT_FLAG_MODULUS_PRIME, pbScratch, cbScratch ); // tmp = 1/(z * a)
244 SymCryptModMul( pCurve->FMod, pCurve->B, peTmp, peX1, pbScratch, cbScratch ); // x1A = B * 1/(z * a)
245
246 SymCryptModInv( pCurve->FMod, pCurve->A, peTmp, SYMCRYPT_FLAG_DATA_PUBLIC | SYMCRYPT_FLAG_MODULUS_PRIME, pbScratch, cbScratch ); // tmp = 1/a
247 SymCryptModMul( pCurve->FMod, pCurve->B, peTmp, peTmp, pbScratch, cbScratch ); // tmp = b * 1/a
248 SymCryptModNeg( pCurve->FMod, peTmp, peTmp, pbScratch, cbScratch ); // tmp = -(b * 1/a)
249
250 // NB: in this block we're using X2 as the second candidate for CSEL. This allows us to choose the
251 // correct X1 by copying X2 to X1 if l is false
252 SymCryptIntSetValueUint32( 1, piTmp );
253 SymCryptIntToModElement( piTmp, pCurve->FMod, peX2, pbScratch, cbScratch ); // X1B = 1
254 SymCryptModAdd( pCurve->FMod, peX2, peT, peX2, pbScratch, cbScratch ); // X1B = 1 + t
255 SymCryptModMul( pCurve->FMod, peX2, peTmp, peX2, pbScratch, cbScratch ); // X1B = -(b * 1/a)(1 + t)
256
257 // Note: we need the binary complement of l since MaskedCopy copies only if the mask is 0xFFFFFFFF,
258 // and we want the second X1 candidate iff l is false
259 SymCryptModElementMaskedCopy( pCurve->FMod, peX2, peX1, ~selectionMask );
260
261 // gx1 = ( x1^3 + a * x1 + b ) = (x1^2 + a)*x1 + b modulo p
262 SymCryptModSquare( pCurve->FMod, peX1, peGX1, pbScratch, cbScratch ); // gx1 = x1^2
263 SymCryptModAdd( pCurve->FMod, peGX1, pCurve->A, peGX1, pbScratch, cbScratch ); // gx1 = x1^2 + a
264 SymCryptModMul( pCurve->FMod, peGX1, peX1, peGX1, pbScratch, cbScratch ); // gx1 = (x1^2 + a)*x1
265 SymCryptModAdd( pCurve->FMod, peGX1, pCurve->B, peGX1, pbScratch, cbScratch ); // gx1 = (x1^2 + a)*x1 + b
266
267 //x2 = ( z * u^2 * x1 ) modulo p
268 SymCryptModSquare( pCurve->FMod, peU, peX2, pbScratch, cbScratch ); // x2 = u^2
269 SymCryptModMul( pCurve->FMod, peX2, peZ, peX2, pbScratch, cbScratch ); // x2 = u^2 * z
270 SymCryptModMul( pCurve->FMod, peX2, peX1, peX2, pbScratch, cbScratch ); // x2 = u^2 * z * x1
271
272 //gx2 = ( x2^3 + a * x2 + b ) = (x2^2 + a)*x2 + b modulo p
273 SymCryptModSquare( pCurve->FMod, peX2, peGX2, pbScratch, cbScratch ); // gx2 = x2^2
274 SymCryptModAdd( pCurve->FMod, peGX2, pCurve->A, peGX2, pbScratch, cbScratch ); // gx2 = x2^2 + a
275 SymCryptModMul( pCurve->FMod, peGX2, peX2, peGX2, pbScratch, cbScratch ); // gx2 = (x2^2 + a)*x2
276 SymCryptModAdd( pCurve->FMod, peGX2, pCurve->B, peGX2, pbScratch, cbScratch ); // gx2 = (x2^2 + a)*x2 + b
277
278 //l = gx1 is a quadratic residue modulo p
279 scError = SymCryptModSqrt( pCurve->FMod, peGX1, &selectionMask, NULL, pbScratch, cbScratch );
280 if( scError != SYMCRYPT_NO_ERROR )
281 {
282 goto cleanup;
283 }
284
285 // v = CSEL( l, gx1, gx2 )
286 // (Using gx1 as a temporary for v)
287 SymCryptModElementMaskedCopy( pCurve->FMod, peGX2, peGX1, ~selectionMask );
288
289 // x = CSEL( l, x1, x2 )
290 // (Using x1 as a temporary for x)
291 SymCryptModElementMaskedCopy( pCurve->FMod, peX2, peX1, ~selectionMask );
292
293 // y = sqrt( v ) = v^{(P+1)/4}
294 // (Using gx1 as a temporary for y)
295 scError = SymCryptModSqrt( pCurve->FMod, peGX1, &selectionMask, peGX1, pbScratch, cbScratch );
296
297 // l = CEQ( LSB( u ), LSB( y ) )
298 // LSB returns the least significant *BIT* of its argument
299 SymCryptModElementToInt( pCurve->FMod, peU, piTmp, pbScratch, cbScratch );
301
302 SymCryptModElementToInt( pCurve->FMod, peGX1, piTmp, pbScratch, cbScratch );
304
305 selectionMask = SYMCRYPT_MASK32_EQ( u & 1, y & 1 );
306
307 // P = CSEL( l, ( x, y ), ( x, p - y ) )
308 // equivalently, y = CSEL( l, y, p - y )
309 // (p - y) mod p is equivalent to -y mod p, so we end up with
310 // y = CSEL(l, y, -y)
311 // We use gx1 for y
312 SymCryptModNeg( pCurve->FMod, peGX1, peTmp, pbScratch, cbScratch );
313 SymCryptModElementMaskedCopy( pCurve->FMod, peTmp, peGX1, ~selectionMask );
314
315 SymCryptModElementGetValue( pCurve->FMod, peX1, &pointBuf[0], pCurve->FModBytesize, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pbScratch, cbScratch );
316 SymCryptModElementGetValue( pCurve->FMod, peGX1, &pointBuf[pCurve->FModBytesize], pCurve->FModBytesize, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pbScratch, cbScratch );
317
319 pointBuf,
320 2 * pCurve->FModBytesize,
323 poP,
324 0,
325 pbScratch,
326 cbScratch );
327 if( scError != SYMCRYPT_NO_ERROR )
328 {
329 goto cleanup;
330 }
331
332cleanup:
333
334 if( peGX2 != NULL )
335 {
336 SymCryptModElementFree( pCurve->FMod, peGX2 );
337 peGX2 = NULL;
338 }
339
340 if( peGX1 != NULL )
341 {
342 SymCryptModElementFree( pCurve->FMod, peGX1 );
343 peGX1 = NULL;
344 }
345
346 if( peX2 != NULL )
347 {
348 SymCryptModElementFree( pCurve->FMod, peX2 );
349 peX2 = NULL;
350 }
351
352 if( peX1 != NULL )
353 {
354 SymCryptModElementFree( pCurve->FMod, peX1 );
355 peX1 = NULL;
356 }
357
358 if( peT != NULL )
359 {
360 SymCryptModElementFree( pCurve->FMod, peT );
361 peT = NULL;
362 }
363
364 if( peM != NULL )
365 {
366 SymCryptModElementFree( pCurve->FMod, peM );
367 peM = NULL;
368 }
369
370 if( peZ != NULL )
371 {
372 SymCryptModElementFree( pCurve->FMod, peZ );
373 peZ = NULL;
374 }
375
376 if( peTmp != NULL )
377 {
378 SymCryptModElementFree( pCurve->FMod, peTmp );
379 peTmp = NULL;
380 }
381
382 if( piTmp != NULL )
383 {
384 SymCryptIntFree( piTmp );
385 piTmp = NULL;
386 }
387
388 return scError;
389}
390
394 _Inout_updates_opt_( cbRand ) PBYTE pbRand,
395 SIZE_T cbRand,
396 _Inout_updates_opt_( cbMask) PBYTE pbMask,
397 SIZE_T cbMask,
400{
401 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
402
403 PCSYMCRYPT_ECURVE pcCurve = pState->pCurve;
404
405 SymCryptModElementSetValueUint32( 0, pcCurve->GOrd, pState->peRand, pbScratch, cbScratch );
406 if( pbRand != NULL )
407 {
408 scError = SymCryptModElementSetValue( pbRand, cbRand, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pcCurve->GOrd, pState->peRand, pbScratch, cbScratch );
409 if( scError != SYMCRYPT_NO_ERROR )
410 {
411 goto cleanup;
412 }
413 }
414
415 if( SymCryptModElementIsZero( pcCurve->GOrd, pState->peRand ) )
416 {
418 }
419
420 if( pbRand != NULL )
421 {
422 scError = SymCryptModElementGetValue( pcCurve->GOrd, pState->peRand, pbRand, cbRand, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pbScratch, cbScratch );
423 if( scError != SYMCRYPT_NO_ERROR )
424 {
425 goto cleanup;
426 }
427 }
428
429 SymCryptModElementSetValueUint32( 0, pcCurve->GOrd, pState->peMask, pbScratch, cbScratch );
430 if( pbMask != NULL )
431 {
432 scError = SymCryptModElementSetValue( pbMask, cbMask, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pcCurve->GOrd, pState->peMask, pbScratch, cbScratch );
433 if( scError != SYMCRYPT_NO_ERROR )
434 {
435 goto cleanup;
436 }
437 }
438
439 if( SymCryptModElementIsZero( pcCurve->GOrd, pState->peMask ) )
440 {
442 }
443
444 if( pbMask != NULL )
445 {
446 scError = SymCryptModElementGetValue( pcCurve->GOrd, pState->peMask, pbMask, cbMask, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pbScratch, cbScratch );
447 if( scError != SYMCRYPT_NO_ERROR )
448 {
449 goto cleanup;
450 }
451 }
452
453 //
454 // The standard calls for checking that peRand and peMask are not 0 or 1, and peRand + peMask is not 0 or 1.
455 // When the caller specifies the values we don't want to do any checking as they might be helpful in test vectors.
456 // When this code generates the random values, we avoid 0 or 1 (by not passing the flags allowing 0 and 1).
457 // We don't check that peRand + peMask > 1 because the probability of that occurring randomly is about 2^{-254} so the
458 // risk of this happening on any machine ever in the world is much smaller than the risk associated with adding several lines of code.
459 //
460
461cleanup:
462
463 return scError;
464}
465
469 _In_reads_( 6 ) PCBYTE pbMac1,
470 _In_reads_( 6 ) PCBYTE pbMac2,
471 _In_reads_( cbPassword ) PCBYTE pbPassword,
472 SIZE_T cbPassword,
473 _Out_opt_ PBYTE pbCounter,
474 _Inout_updates_opt_( 32 ) PBYTE pbRand,
475 _Inout_updates_opt_( 32 ) PBYTE pbMask )
476{
477 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
478
480 UINT32 notFoundMask;
481 UINT32 solutionMask;
482 UINT32 negMask;
485 BYTE abSeedKey[16]; // Need only 12, but the extra bytes make the code easier.
489 BYTE abTmp[2];
490 BYTE pointBuf[ 64 ];
491 PBYTE pbScratch = NULL;
492 SIZE_T cbScratch = 0;
493 UINT64 minMac;
494 UINT64 maxMac;
495
496 UINT32 nDigits;
497 PSYMCRYPT_ECURVE pCurve; // Only a cache, pState->pCurve owns the allocation
498 PSYMCRYPT_INT piTmp = NULL;
501 PSYMCRYPT_MODELEMENT peCubic = NULL;
503 PSYMCRYPT_ECPOINT poPWECandidate = NULL;
504
505 // Set state to 0 so that our pointers have valid values.
506 SymCryptWipe( pState, sizeof( *pState ) );
507
508 // Per IEEE 802.11-2016 section 12.4.4.1 the mandatory-to-implement curve is
509 // number 19 from the IANA Group description for RFC 2409 (IKE)
510 // The IANA website maps this to a 256-bit Random ECP group in RFC 5903.
511 // RFC 5903 specifies this group to be identical to the NIST P256 curve.
513 pState->pCurve = pCurve;
514 if( pCurve == NULL )
515 {
516 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
517 goto cleanup;
518 }
519
520 pState->macAlgorithm = SymCryptHmacSha256Algorithm;
521
522 pState->peRand = SymCryptModElementAllocate( pCurve->GOrd );
523 if( pState->peRand == NULL )
524 {
525 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
526 goto cleanup;
527 }
528
529 pState->peMask = SymCryptModElementAllocate( pCurve->GOrd );
530 if( pState->peMask == NULL )
531 {
532 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
533 goto cleanup;
534 }
535
537 if( pState->poPWE == NULL )
538 {
539 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
540 goto cleanup;
541 }
542
544
548 pbScratch = SymCryptCallbackAlloc( cbScratch );
549
550 piTmp = SymCryptIntAllocate( nDigits );
551 peX = SymCryptModElementAllocate( pCurve->FMod );
552 peY = SymCryptModElementAllocate( pCurve->FMod );
553 peCubic = SymCryptModElementAllocate( pCurve->FMod );
554 peTmp = SymCryptModElementAllocate( pCurve->FMod );
555 poPWECandidate = SymCryptEcpointAllocate( pCurve );
556
557 if( pbScratch == NULL || piTmp == NULL || peX == NULL || peY == NULL || peCubic == NULL || peTmp == NULL || poPWECandidate == NULL )
558 {
559 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
560 goto cleanup;
561 }
562
563 SymCryptWipeKnownSize( abSeedKey, sizeof( abSeedKey ) );
564 memcpy( &abSeedKey[0], pbMac1, 6 );
565 minMac = SYMCRYPT_LOAD_MSBFIRST64( abSeedKey );
566 memcpy( &abSeedKey[0], pbMac2, 6 );
567 maxMac = SYMCRYPT_LOAD_MSBFIRST64( abSeedKey );
568
569 if( minMac > maxMac )
570 {
571 // MAC values are public, no side-channel issues with this if()
572 // Swap the two values
573 minMac ^= maxMac;
574 maxMac ^= minMac;
575 minMac ^= maxMac;
576 }
577
578 // Now we write the two MACs into the buffer.
579 // Note the slight overlap, and the use of 14 bytes rather than 12
580 SYMCRYPT_STORE_MSBFIRST64( &abSeedKey[0], maxMac );
581 SYMCRYPT_STORE_MSBFIRST64( &abSeedKey[6], minMac ); // This writes up to abSeedKey[14]
582
583 SymCryptHmacSha256ExpandKey( &hmacSeedKey, abSeedKey, 12 );
584 SymCryptWipeKnownSize( abSeedKey, sizeof( abSeedKey ) ); // Not strictly speaking a secret, but good general hygiene
585
586 notFoundMask = (UINT32)-1;
587 counter = 0;
588
589 // We exit the loop only after 40 or more iterations
590 // This greatly reduces the side-channel of how often we run this loop.
591 while( notFoundMask != 0 || counter < 40 )
592 {
593 counter += 1;
594 if( counter == 0 )
595 {
596 scError = SYMCRYPT_INVALID_ARGUMENT;
597 goto cleanup;
598 }
599
600 // pwd-seed = Hmac-sha256( MacA || MacB , Password || counter )
601 SymCryptHmacSha256Init( &hmacState, &hmacSeedKey );
602 SymCryptHmacSha256Append( &hmacState, pbPassword, cbPassword );
603 SymCryptHmacSha256Append( &hmacState, &counter, 1 );
604 SymCryptHmacSha256Result( &hmacState, abSeed );
605
606 // pwd-value
607 SymCryptHmacSha256ExpandKey( &hmacValueKey, abSeed, sizeof( abSeed ) );
608 SymCryptHmacSha256Init( &hmacState, &hmacValueKey );
609
610 SYMCRYPT_STORE_LSBFIRST16( abTmp, 1 );
611 SymCryptHmacSha256Append( &hmacState, abTmp, 2 ); // i value = 1
612 // Spec is unclear on whether there should be a terminating 0 on the context
613 // There are 23 characters in the string, so using len=24 gives us a zero
614 SymCryptHmacSha256Append( &hmacState, (PCBYTE) "SAE Hunting and Pecking", 23 );
615
616 // Pick up the byte representation of p from the parameters
618
619 SYMCRYPT_STORE_LSBFIRST16( abTmp, 256 );
620 SymCryptHmacSha256Append( &hmacState, abTmp, 2 ); // Length value = 256
621 SymCryptHmacSha256Result( &hmacState, abValue );
622
623 // Get the pwd-value into an integer
624 scError = SymCryptIntSetValue( abValue, sizeof( abValue ), SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, piTmp );
625 if( scError != SYMCRYPT_NO_ERROR )
626 {
627 goto cleanup;
628 }
629
630 // Check that it is less than P
631 if( !SymCryptIntIsLessThan( piTmp, SymCryptIntFromModulus( pCurve->FMod ) ) )
632 {
633 // This is a slight side-channel, but our prime P starts with FFFFFFFF so the probability of
634 // hitting this case is < 2^-32.
635 continue;
636 }
637
638 // Compute x^3 + A*x + B
639 SymCryptIntToModElement( piTmp, pCurve->FMod, peX, pbScratch, cbScratch );
640 SymCryptModSquare( pCurve->FMod, peX, peCubic, pbScratch, cbScratch );
641 SymCryptModAdd( pCurve->FMod, peCubic, pCurve->A, peCubic, pbScratch, cbScratch );
642 SymCryptModMul( pCurve->FMod, peCubic, peX, peCubic, pbScratch, cbScratch );
643 SymCryptModAdd( pCurve->FMod, peCubic, pCurve->B, peCubic, pbScratch, cbScratch );
644
645 // Get the quadratic residue of (x^3 + A*x + B) modulo P if it exists
646 scError = SymCryptModSqrt( pCurve->FMod, peCubic, &solutionMask, peY, pbScratch, cbScratch );
647 if( scError != SYMCRYPT_NO_ERROR )
648 {
649 goto cleanup;
650 }
651
652 solutionMask &= notFoundMask;
653
654 // Pick Y or -Y according to the LSbits
655 SymCryptModElementToInt( pCurve->FMod, peY, piTmp, pbScratch, cbScratch );
656 SymCryptModNeg( pCurve->FMod, peY, peTmp, pbScratch, cbScratch );
657
658 negMask = 0 - ((abSeed[ sizeof( abSeed ) - 1 ] ^ SymCryptIntGetValueLsbits32( piTmp ) ) & 1);
659 SymCryptModElementMaskedCopy( pCurve->FMod, peTmp, peY, negMask );
660
661 SymCryptModElementGetValue( pCurve->FMod, peX, &pointBuf[ 0], 32, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pbScratch, cbScratch );
662 SymCryptModElementGetValue( pCurve->FMod, peY, &pointBuf[32], 32, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pbScratch, cbScratch );
664 pointBuf,
665 sizeof( pointBuf ),
668 poPWECandidate,
669 0,
670 pbScratch,
671 cbScratch );
672 if( scError != SYMCRYPT_NO_ERROR )
673 {
674 goto cleanup;
675 }
676
677 SymCryptEcpointMaskedCopy( pCurve, poPWECandidate, pState->poPWE, solutionMask );
678 pState->counter |= (BYTE)(counter & solutionMask);
679
680 notFoundMask &= ~solutionMask;
681 }
682
683 scError = SymCrypt802_11SaeCustomSetRandMask( pState, pbRand, 32, pbMask, 32, pbScratch, cbScratch );
684 if( scError != SYMCRYPT_NO_ERROR)
685 {
686 goto cleanup;
687 }
688
689 if( pbCounter != NULL )
690 {
691 *pbCounter = pState->counter;
692 }
693
694cleanup:
695
696 SymCryptWipe( &hmacSeedKey, sizeof( hmacSeedKey ) );
697 SymCryptWipe( &hmacValueKey, sizeof( hmacValueKey ) );
698 SymCryptWipe( abSeed, sizeof( abSeed ) );
699 SymCryptWipe( abValue, sizeof( abValue ) );
700 SymCryptWipe( pointBuf, sizeof( pointBuf ) );
701
702 if( piTmp != NULL )
703 {
704 SymCryptIntFree( piTmp );
705 piTmp = NULL;
706 }
707
708 if( peX != NULL )
709 {
710 SymCryptModElementFree( pCurve->FMod, peX );
711 peX = NULL;
712 }
713
714 if( peY != NULL )
715 {
716 SymCryptModElementFree( pCurve->FMod, peY );
717 peY = NULL;
718 }
719
720 if( peCubic != NULL )
721 {
722 SymCryptModElementFree( pCurve->FMod, peCubic );
723 peCubic = NULL;
724 }
725
726 if( peTmp != NULL )
727 {
728 SymCryptModElementFree( pCurve->FMod, peTmp );
729 peTmp = NULL;
730 }
731
732 if( poPWECandidate != NULL )
733 {
734 SymCryptEcpointFree( pCurve, poPWECandidate );
735 poPWECandidate = NULL;
736 }
737
738 if( scError != SYMCRYPT_NO_ERROR )
739 {
741 }
742
743 if( pbScratch != NULL )
744 {
745 SymCryptWipe( pbScratch, cbScratch );
746 SymCryptCallbackFree( pbScratch );
747 pbScratch = NULL;
748 }
749
750 return scError;
751}
752
753
757 _In_reads_( cbSsid ) PCBYTE pbSsid,
758 SIZE_T cbSsid,
759 _In_reads_( cbPassword ) PCBYTE pbPassword,
760 SIZE_T cbPassword,
761 _In_reads_opt_( cbPasswordIdentifier ) PCBYTE pbPasswordIdentifier,
762 SIZE_T cbPasswordIdentifier,
763 _Out_writes_( cbPT ) PBYTE pbPT,
764 SIZE_T cbPT)
765{
766 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
767
768 SIZE_T cbIkm = 0;
769 SIZE_T cbScratch = 0;
770
771 PBYTE pbPwdValue = NULL;
772 UINT32 cbPwdValue = 0;
773 PBYTE pbScratch = NULL;
775
777 PCSYMCRYPT_MAC pMacAlgorithm = NULL;
778 PSYMCRYPT_INT piU1 = NULL;
779 PSYMCRYPT_INT piU2 = NULL;
782
783 PSYMCRYPT_ECPOINT poP1 = NULL;
784 PSYMCRYPT_ECPOINT poP2 = NULL;
785 PSYMCRYPT_ECPOINT poPT = NULL;
786
787 PCSYMCRYPT_SAE_GROUP_DATA pGroupData = NULL;
788
789
790 pGroupData = SymCryptSaeFindGroupData( group );
791
792 // Provided IANA group number must match one of the supported groups
793 if ( pGroupData == NULL)
794 {
795 scError = SYMCRYPT_INVALID_ARGUMENT;
796 goto cleanup;
797 }
798
799 // Construct the objects associated with the IANA group number
800 pCurve = SymCryptEcurveAllocate( *( pGroupData->pCurveParams), 0 );
801 if( pCurve == NULL )
802 {
803 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
804 goto cleanup;
805 }
806
807 pMacAlgorithm = *( pGroupData->macAlgorithm );
808
810
811 cbIkm = cbPassword + cbPasswordIdentifier;
812 cbScratch = SYMCRYPT_MAX( cbIkm,
817 pbScratch = SymCryptCallbackAlloc( cbScratch );
818
819 // len = olen( p ) + floor( olen( p ) / 2 )
820 cbPwdValue = SYMCRYPT_BYTES_FROM_BITS(pCurve->FModBitsize) + SYMCRYPT_BYTES_FROM_BITS(pCurve->FModBitsize) / 2;
821
822 pbPwdValue = SymCryptCallbackAlloc( cbPwdValue );
823
824 piU1 = SymCryptIntAllocate( SymCryptDigitsFromBits( cbPwdValue * 8 ) );
825 piU2 = SymCryptIntAllocate( SymCryptDigitsFromBits( cbPwdValue * 8 ) );
826 peU1 = SymCryptModElementAllocate( pCurve->FMod );
827 peU2 = SymCryptModElementAllocate( pCurve->FMod );
828
832
833 if( pbScratch == NULL || pbPwdValue == NULL || piU1 == NULL || piU2 == NULL ||
834 peU1 == NULL || peU2 == NULL || poP1 == NULL || poP2 == NULL || poPT == NULL)
835 {
836 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
837 goto cleanup;
838 }
839
840 // pwd-seed = HKDF-Extract( ssid, password [|| identifier] )
841 // Note that SymCryptHkdfExpandKey corresponds to HKDF-Extract
842 memcpy( pbScratch, pbPassword, cbPassword );
843 if( pbPasswordIdentifier )
844 {
845 memcpy( pbScratch + cbPassword, pbPasswordIdentifier, cbPasswordIdentifier );
846 }
847
848 scError = SymCryptHkdfExpandKey( &hkdfKey, pMacAlgorithm, pbScratch, cbIkm, pbSsid, cbSsid );
849 if( scError != SYMCRYPT_NO_ERROR )
850 {
851 goto cleanup;
852 }
853
854 // pwd-value = HKDF-Expand( pwd-seed, "SAE Hash to Element u1 P1", len )
855 // Note that SymCryptHkdf derive corresponds to HKDF-Expand
856 // Salt does not include a null terminator, so the length is 25 chars
857 scError = SymCryptHkdfDerive( &hkdfKey, (PCBYTE) "SAE Hash to Element u1 P1", 25, pbPwdValue, cbPwdValue );
858 if( scError != SYMCRYPT_NO_ERROR )
859 {
860 goto cleanup;
861 }
862
863 // u1 = pwd-value modulo p
864 scError = SymCryptIntSetValue( pbPwdValue, cbPwdValue, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, piU1 );
865 if( scError != SYMCRYPT_NO_ERROR )
866 {
867 goto cleanup;
868 }
869
870 SymCryptIntToModElement( piU1, pCurve->FMod, peU1, pbScratch, cbScratch );
871
872 // P1 = SSWU( u1 )
873 SymCryptSswu( pCurve, pGroupData->z, peU1, poP1, pbScratch, cbScratch );
874
875 // pwd-value = HKDF-Expand( pwd-seed, "SAE Hash to Element u2 P2", len )
876 scError = SymCryptHkdfDerive( &hkdfKey, (PCBYTE) "SAE Hash to Element u2 P2", 25, pbPwdValue, cbPwdValue );
877 if( scError != SYMCRYPT_NO_ERROR )
878 {
879 goto cleanup;
880 }
881
882 // u2 = pwd-value modulo p
883 scError = SymCryptIntSetValue( pbPwdValue, cbPwdValue, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, piU2 );
884 if( scError != SYMCRYPT_NO_ERROR )
885 {
886 goto cleanup;
887 }
888
889 SymCryptIntToModElement( piU2, pCurve->FMod, peU2, pbScratch, cbScratch );
890
891 // P2 = SSWU( u2 )
892 scError = SymCryptSswu( pCurve, pGroupData->z, peU2, poP2, pbScratch, cbScratch );
893 if( scError != SYMCRYPT_NO_ERROR )
894 {
895 goto cleanup;
896 }
897
898 // PT = P1 + P2
899 SymCryptEcpointAdd( pCurve, poP1, poP2, poPT, 0, pbScratch, cbScratch );
900
902 poPT,
905 pbPT,
906 cbPT,
907 0,
908 pbScratch,
909 cbScratch );
910 SYMCRYPT_ASSERT( scError == SYMCRYPT_NO_ERROR );
911
912cleanup:
913
914 if( poP2 != NULL )
915 {
917 poP2 = NULL;
918 }
919
920 if( poP1 != NULL )
921 {
923 poP1 = NULL;
924 }
925
926 if( poPT != NULL )
927 {
929 poPT = NULL;
930 }
931
932 if( peU2 != NULL )
933 {
934 SymCryptModElementFree( pCurve->FMod, peU2 );
935 peU2 = NULL;
936 }
937
938 if( peU1 != NULL )
939 {
940 SymCryptModElementFree( pCurve->FMod, peU1 );
941 peU1 = NULL;
942 }
943
944 if( piU2 != NULL )
945 {
946 SymCryptIntFree( piU2 );
947 piU2 = NULL;
948 }
949
950 if( piU1 != NULL )
951 {
952 SymCryptIntFree( piU1 );
953 piU1 = NULL;
954 }
955
956 if( pbPwdValue != NULL )
957 {
958 SymCryptWipe( pbPwdValue, cbPwdValue );
959 SymCryptCallbackFree( pbPwdValue );
960 pbPwdValue = NULL;
961 }
962
963 if( pbScratch != NULL )
964 {
965 SymCryptWipe( pbScratch, cbScratch );
966 SymCryptCallbackFree( pbScratch );
967 pbScratch = NULL;
968 }
969
970 if ( pCurve != NULL )
971 {
973 pCurve = NULL;
974 }
975
976 return scError;
977}
978
979
982 _In_reads_( cbSsid ) PCBYTE pbSsid,
983 SIZE_T cbSsid,
984 _In_reads_( cbPassword ) PCBYTE pbPassword,
985 SIZE_T cbPassword,
986 _In_reads_opt_( cbPasswordIdentifier ) PCBYTE pbPasswordIdentifier,
987 SIZE_T cbPasswordIdentifier,
988 _Out_writes_( 64 ) PBYTE pbPT )
989{
991 pbSsid,
992 cbSsid,
993 pbPassword,
994 cbPassword,
995 pbPasswordIdentifier,
996 cbPasswordIdentifier,
997 pbPT,
998 64 );
999}
1000
1001
1006 _In_reads_( cbPT ) PCBYTE pbPT,
1007 SIZE_T cbPT,
1008 _In_reads_( 6 ) PCBYTE pbMacA,
1009 _In_reads_( 6 ) PCBYTE pbMacB,
1010 _Inout_updates_opt_( cbRand ) PBYTE pbRand,
1011 SIZE_T cbRand,
1012 _Inout_updates_opt_( cbMask ) PBYTE pbMask,
1013 SIZE_T cbMask)
1014{
1015 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
1016
1017 BYTE hmacKeyBytes[SYMCRYPT_SAE_MAX_HMAC_OUTPUT_SIZE_BYTES] = { 0 };
1019 BYTE macBuffer[16] = { 0 }; // Need only 12, but the extra bytes make the code easier.
1020 SYMCRYPT_MAC_EXPANDED_KEY hmacKey = { 0 };
1021 SYMCRYPT_MAC_STATE hmacState = { 0 };
1022
1023 SIZE_T cbScratch = 0;
1024 PBYTE pbScratch = NULL;
1025
1026 UINT64 minMac = 0;
1027 UINT64 maxMac = 0;
1028
1029 UINT32 nDigits = 0;
1030
1031 PSYMCRYPT_INT piTmp = NULL;
1032 PSYMCRYPT_MODULUS pmMod = NULL;
1033 PSYMCRYPT_MODELEMENT peVal = NULL;
1034 PSYMCRYPT_MODELEMENT peTmp = NULL;
1035 PSYMCRYPT_ECPOINT poPT = NULL;
1036 PCSYMCRYPT_SAE_GROUP_DATA pGroupData = NULL;
1037 PCSYMCRYPT_MAC pMacAlgorithm = NULL;
1038
1039 // Set state to 0 so that our pointers have valid values.
1040 SymCryptWipeKnownSize( pState, sizeof( *pState ) );
1041
1042 PSYMCRYPT_ECURVE pCurve = NULL; // Weak reference; curve is owned by pState
1043
1044 pGroupData = SymCryptSaeFindGroupData( group );
1045
1046 // Provided IANA group number must match one of the supported groups
1047 if ( pGroupData == NULL )
1048 {
1049 scError = SYMCRYPT_INVALID_ARGUMENT;
1050 goto cleanup;
1051 }
1052
1053 // Construct the objects associated with the IANA group number
1054 pCurve = SymCryptEcurveAllocate( *( pGroupData->pCurveParams ), 0 );
1055 if ( pCurve == NULL )
1056 {
1057 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
1058 goto cleanup;
1059 }
1060
1061 pState->pCurve = pCurve;
1062
1063 pMacAlgorithm = *( pGroupData->macAlgorithm );
1064
1065 SIZE_T cbHMACOutputSize = pMacAlgorithm->resultSize;
1066
1067 pState->peRand = SymCryptModElementAllocate( pCurve->GOrd );
1068 if( pState->peRand == NULL )
1069 {
1070 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
1071 goto cleanup;
1072 }
1073
1074 pState->peMask = SymCryptModElementAllocate( pCurve->GOrd );
1075 if( pState->peMask == NULL )
1076 {
1077 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
1078 goto cleanup;
1079 }
1080
1082 if( pState->poPWE == NULL )
1083 {
1084 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
1085 goto cleanup;
1086 }
1087
1088 nDigits = SymCryptDigitsFromBits( pCurve->GOrdBitsize );
1089
1090 piTmp = SymCryptIntAllocate( nDigits );
1091 pmMod = SymCryptModulusAllocate( nDigits );
1093
1098 pbScratch = SymCryptCallbackAlloc( cbScratch );
1099
1100 if( piTmp == NULL || pmMod == NULL || poPT == NULL || pbScratch == NULL )
1101 {
1102 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
1103 goto cleanup;
1104 }
1105
1106 memcpy( &macBuffer[0], pbMacA, 6 );
1107 minMac = SYMCRYPT_LOAD_MSBFIRST64( macBuffer );
1108 memcpy( &macBuffer[0], pbMacB, 6 );
1109 maxMac = SYMCRYPT_LOAD_MSBFIRST64( macBuffer );
1110
1111 if( minMac > maxMac )
1112 {
1113 // MAC values are public, no side-channel issues with this if()
1114 // Swap the two values
1115 minMac ^= maxMac;
1116 maxMac ^= minMac;
1117 minMac ^= maxMac;
1118 }
1119
1120 // Now we write the two MACs into the buffer.
1121 // Note the slight overlap, and the use of 14 bytes rather than 12
1122 SYMCRYPT_STORE_MSBFIRST64( &macBuffer[0], maxMac );
1123 SYMCRYPT_STORE_MSBFIRST64( &macBuffer[6], minMac ); // This writes up to macBuffer[14]
1124
1125 // val = hmac-sha256( 0^n, maxMac || minMac )
1126 // The HMAC key is is a buffer of all zeros whose length equals the length of the digest from the hash function
1127 pMacAlgorithm->expandKeyFunc(&hmacKey, hmacKeyBytes, cbHMACOutputSize);
1128
1129 pMacAlgorithm->initFunc( &hmacState, &hmacKey );
1130 pMacAlgorithm->appendFunc( &hmacState, macBuffer, 12 );
1131 pMacAlgorithm->resultFunc( &hmacState, valBytes );
1132
1133 // val = val (#4666)modulo (q - 1) + 1
1135 SymCryptIntToModulus( piTmp, pmMod, 1, SYMCRYPT_FLAG_DATA_PUBLIC, pbScratch, cbScratch );
1136
1137 peVal = SymCryptModElementAllocate( pmMod );
1138 peTmp = SymCryptModElementAllocate( pmMod );
1139
1140 if( peVal == NULL || peTmp == NULL )
1141 {
1142 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
1143 goto cleanup;
1144 }
1145
1146 scError = SymCryptModElementSetValue( valBytes, cbHMACOutputSize, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pmMod, peVal, pbScratch, cbScratch );
1147 if( scError != SYMCRYPT_NO_ERROR )
1148 {
1149 goto cleanup;
1150 }
1151
1152 SymCryptModElementSetValueUint32( 1, pmMod, peTmp, pbScratch, cbScratch );
1153 SymCryptModAdd( pmMod, peVal, peTmp, peVal, pbScratch, cbScratch );
1154
1155 SymCryptModElementToInt( pmMod, peVal, piTmp, pbScratch, cbScratch );
1156
1158 pbPT,
1159 cbPT,
1162 poPT,
1163 0,
1164 pbScratch,
1165 cbScratch );
1166 if( scError != SYMCRYPT_NO_ERROR )
1167 {
1168 goto cleanup;
1169 }
1170
1171 scError = SymCryptEcpointScalarMul( pCurve, piTmp, poPT, 0, pState->poPWE, pbScratch, cbScratch );
1172 if( scError != SYMCRYPT_NO_ERROR )
1173 {
1174 goto cleanup;
1175 }
1176
1177 scError = SymCrypt802_11SaeCustomSetRandMask( pState, pbRand, cbRand, pbMask, cbMask, pbScratch, cbScratch );
1178 if( scError != SYMCRYPT_NO_ERROR )
1179 {
1180 goto cleanup;
1181 }
1182
1183cleanup:
1184
1185 if( peTmp != NULL )
1186 {
1187 SymCryptModElementFree( pmMod, peTmp );
1188 peTmp = NULL;
1189 }
1190
1191 if( peVal != NULL )
1192 {
1193 SymCryptModElementFree( pmMod, peVal );
1194 peVal = NULL;
1195 }
1196
1197 if( poPT != NULL )
1198 {
1199 SymCryptEcpointFree( pCurve, poPT );
1200 poPT = NULL;
1201 }
1202
1203 if( pmMod != NULL )
1204 {
1205 SymCryptModulusFree( pmMod );
1206 pmMod = NULL;
1207 }
1208
1209 if( piTmp != NULL )
1210 {
1211 SymCryptIntFree( piTmp );
1212 piTmp = NULL;
1213 }
1214
1215 if( pbScratch != NULL )
1216 {
1217 SymCryptWipe( pbScratch, cbScratch );
1218 SymCryptCallbackFree( pbScratch );
1219 pbScratch = NULL;
1220 }
1221
1222 if( scError != SYMCRYPT_NO_ERROR )
1223 {
1225 }
1226
1227 return scError;
1228}
1229
1233 _In_reads_( 64 ) PCBYTE pbPT,
1234 _In_reads_( 6 ) PCBYTE pbMacA,
1235 _In_reads_( 6 ) PCBYTE pbMacB,
1236 _Inout_updates_opt_( 32 ) PBYTE pbRand,
1237 _Inout_updates_opt_( 32 ) PBYTE pbMask )
1238{
1241 pbPT,
1242 64,
1243 pbMacA,
1244 pbMacB,
1245 pbRand,
1246 32,
1247 pbMask,
1248 32 );
1249}
1250
1251
1252VOID
1255{
1256 PSYMCRYPT_ECURVE pCurve = pState->pCurve;
1257
1258 if( pState->poPWE != NULL )
1259 {
1261 }
1262
1263 if( pState->peMask != NULL )
1264 {
1265 SymCryptModElementFree( pCurve->GOrd, pState->peMask );
1266 }
1267
1268 if( pState->peRand != NULL )
1269 {
1270 SymCryptModElementFree( pCurve->GOrd, pState->peRand );
1271 }
1272
1273 if( pCurve != NULL )
1274 {
1276 }
1277
1278 SymCryptWipeKnownSize( pState, sizeof( *pState ) );
1279}
1280
1284 _Out_writes_( cbCommitScalar ) PBYTE pbCommitScalar,
1285 SIZE_T cbCommitScalar,
1286 _Out_writes_( cbCommitElement ) PBYTE pbCommitElement,
1287 SIZE_T cbCommitElement)
1288{
1289 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
1290 PSYMCRYPT_MODELEMENT peTmp = NULL;
1291 PSYMCRYPT_INT piTmp = NULL;
1292 PSYMCRYPT_ECPOINT poPoint = NULL;
1293 PBYTE pbScratch = NULL;
1295 SIZE_T nDigits;
1296
1298
1299 nDigits = SymCryptDigitsFromBits( pCurve->FModBitsize );
1303
1304 pbScratch = SymCryptCallbackAlloc( cbScratch );
1305
1306 peTmp = SymCryptModElementAllocate( pCurve->GOrd );
1308 poPoint = SymCryptEcpointAllocate( pCurve );
1309
1310 if( peTmp == NULL || piTmp == NULL || poPoint == NULL || pbScratch == NULL )
1311 {
1312 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
1313 goto cleanup;
1314 }
1315
1316 SymCryptModAdd( pCurve->GOrd, pState->peRand, pState->peMask, peTmp, pbScratch, cbScratch );
1317 scError = SymCryptModElementGetValue( pCurve->GOrd, peTmp, pbCommitScalar, cbCommitScalar, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pbScratch, cbScratch );
1318 if( scError != SYMCRYPT_NO_ERROR )
1319 {
1320 goto cleanup;
1321 }
1322
1323 SymCryptModElementToInt( pCurve->GOrd, pState->peMask, piTmp, pbScratch, cbScratch );
1325 piTmp,
1326 pState->poPWE,
1327 0,
1328 poPoint,
1329 pbScratch,
1330 cbScratch );
1331 if( scError != SYMCRYPT_NO_ERROR )
1332 {
1333 goto cleanup;
1334 }
1335
1336 // Now we have mask * PWE, but we need the negative...
1337 SymCryptEcpointNegate( pCurve, poPoint, (UINT32)-1, pbScratch, cbScratch );
1338
1340 poPoint,
1343 pbCommitElement,
1344 cbCommitElement,
1345 0,
1346 pbScratch,
1347 cbScratch );
1348 if( scError != SYMCRYPT_NO_ERROR )
1349 {
1350 goto cleanup;
1351 }
1352
1353cleanup:
1354
1355 if( piTmp != NULL )
1356 {
1357 SymCryptIntFree( piTmp );
1358 piTmp = NULL;
1359 }
1360
1361 if( peTmp != NULL )
1362 {
1363 SymCryptModElementFree( pCurve->GOrd, peTmp );
1364 peTmp = NULL;
1365 }
1366
1367 if( poPoint != NULL )
1368 {
1369 SymCryptEcpointFree( pCurve, poPoint );
1370 poPoint = NULL;
1371 }
1372
1373 if( pbScratch != NULL )
1374 {
1375 SymCryptWipe( pbScratch, cbScratch );
1376 SymCryptCallbackFree( pbScratch );
1377 pbScratch = NULL;
1378 }
1379
1380 return scError;
1381}
1382
1386 _Out_writes_( 32 ) PBYTE pbCommitScalar,
1387 _Out_writes_( 64 ) PBYTE pbCommitElement )
1388{
1390 pbCommitScalar,
1391 32,
1392 pbCommitElement,
1393 64 );
1394}
1395
1399 _In_reads_( cbPeerCommitScalar ) PCBYTE pbPeerCommitScalar,
1400 SIZE_T cbPeerCommitScalar,
1401 _In_reads_( cbPeerCommitElement ) PCBYTE pbPeerCommitElement,
1402 SIZE_T cbPeerCommitElement,
1403 _Out_writes_( cbSharedSecret ) PBYTE pbSharedSecret,
1404 SIZE_T cbSharedSecret,
1405 _Out_writes_( cbScalarSum ) PBYTE pbScalarSum,
1406 SIZE_T cbScalarSum )
1407{
1408 SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
1409
1410 PSYMCRYPT_ECURVE pCurve = pState->pCurve;
1411 PSYMCRYPT_MODELEMENT peCommitScalarSum = NULL;
1412 PSYMCRYPT_ECPOINT poPeerCommitElement = NULL;
1413 PSYMCRYPT_ECPOINT poTmp = NULL;
1414 PSYMCRYPT_INT piTmp = NULL;
1415 UINT32 nDigits;
1416
1417 PBYTE pbScratch = NULL;
1419
1420 nDigits = SymCryptDigitsFromBits( pCurve->FModBitsize );
1425 pbScratch = SymCryptCallbackAlloc( cbScratch );
1426
1427 peCommitScalarSum = SymCryptModElementAllocate( pCurve->GOrd );
1428 poPeerCommitElement = SymCryptEcpointAllocate( pCurve );
1431
1432 if( pbScratch == NULL || peCommitScalarSum == NULL || poPeerCommitElement == NULL || poTmp == NULL || piTmp == NULL )
1433 {
1434 scError = SYMCRYPT_MEMORY_ALLOCATION_FAILURE;
1435 goto cleanup;
1436 }
1437
1438 // piTmp = peer commit value
1439 scError = SymCryptIntSetValue( pbPeerCommitScalar, cbPeerCommitScalar, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, piTmp );
1440 if( scError != SYMCRYPT_NO_ERROR )
1441 {
1442 goto cleanup;
1443 }
1444
1445 // The Standard requires a check that the Peer commit value must be 1 < peer-commit < r where r is the group order.
1446 if( !SymCryptIntIsLessThan( piTmp, SymCryptIntFromModulus( pCurve->GOrd ) ) ||
1447 SymCryptIntIsEqualUint32( piTmp, 0 ) ||
1448 SymCryptIntIsEqualUint32( piTmp, 1 ) )
1449 {
1450 scError = SYMCRYPT_INVALID_ARGUMENT;
1451 goto cleanup;
1452 }
1453
1454 SymCryptIntToModElement( piTmp, pCurve->GOrd, peCommitScalarSum, pbScratch, cbScratch );
1455
1456 // Now compute the sum of the scalar commit values
1457 SymCryptModAdd( pCurve->GOrd, peCommitScalarSum, pState->peRand, peCommitScalarSum, pbScratch, cbScratch );
1458 SymCryptModAdd( pCurve->GOrd, peCommitScalarSum, pState->peMask, peCommitScalarSum, pbScratch, cbScratch );
1459
1461 pbPeerCommitElement,
1462 cbPeerCommitElement,
1465 poPeerCommitElement,
1466 0,
1467 pbScratch,
1468 cbScratch );
1469 if( scError != SYMCRYPT_NO_ERROR )
1470 {
1471 goto cleanup;
1472 }
1473
1474 // The EcPointSetValue routine returns an error if either coordinate is >= P.
1475 // We need to check that the point is on the curve and not the zero point of the curve
1476 // (The zero point is sometimes called the 'point at infinity'.)
1477 if( !SymCryptEcpointOnCurve( pCurve, poPeerCommitElement, pbScratch, cbScratch ) ||
1478 SymCryptEcpointIsZero( pCurve, poPeerCommitElement, pbScratch, cbScratch ) )
1479 {
1480 scError = SYMCRYPT_INVALID_ARGUMENT;
1481 goto cleanup;
1482 }
1483
1484
1486 piTmp,
1487 pState->poPWE,
1488 0,
1489 poTmp,
1490 pbScratch,
1491 cbScratch );
1492 if( scError != SYMCRYPT_NO_ERROR )
1493 {
1494 goto cleanup;
1495 }
1496
1497 SymCryptEcpointAdd( pCurve, poTmp, poPeerCommitElement, poTmp, 0, pbScratch, cbScratch );
1498
1499 SymCryptModElementToInt( pCurve->GOrd, pState->peRand, piTmp, pbScratch, cbScratch );
1501 piTmp,
1502 poTmp,
1503 0,
1504 poTmp,
1505 pbScratch,
1506 cbScratch );
1507 if( scError != SYMCRYPT_NO_ERROR )
1508 {
1509 goto cleanup;
1510 }
1511
1513 poTmp,
1516 pbSharedSecret,
1517 cbSharedSecret,
1518 0,
1519 pbScratch,
1520 cbScratch );
1521 if( scError != SYMCRYPT_NO_ERROR )
1522 {
1523 goto cleanup;
1524 }
1525
1526 scError = SymCryptModElementGetValue( pCurve->GOrd, peCommitScalarSum, pbScalarSum, cbScalarSum, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, pbScratch, cbScratch );
1527 if( scError != SYMCRYPT_NO_ERROR )
1528 {
1529 goto cleanup;
1530 }
1531
1532cleanup:
1533
1534 if( peCommitScalarSum != NULL )
1535 {
1536 SymCryptModElementFree( pCurve->GOrd, peCommitScalarSum );
1537 peCommitScalarSum = NULL;
1538 }
1539
1540 if( poPeerCommitElement != NULL )
1541 {
1542 SymCryptEcpointFree( pCurve, poPeerCommitElement );
1543 poPeerCommitElement = NULL;
1544 }
1545
1546 if( poTmp != NULL )
1547 {
1548 SymCryptEcpointFree( pCurve, poTmp );
1549 poTmp = NULL;
1550 }
1551
1552 if( piTmp != NULL )
1553 {
1554 SymCryptIntFree( piTmp );
1555 piTmp = NULL;
1556 }
1557
1558 if( pbScratch != NULL )
1559 {
1560 SymCryptWipe( pbScratch, cbScratch );
1561 SymCryptCallbackFree( pbScratch );
1562 pbScratch = NULL;
1563 }
1564
1565 return scError;
1566}
1567
1571 _In_reads_( 32 ) PCBYTE pbPeerCommitScalar,
1572 _In_reads_( 64 ) PCBYTE pbPeerCommitElement,
1573 _Out_writes_( 32 ) PBYTE pbSharedSecret,
1574 _Out_writes_( 32 ) PBYTE pbScalarSum )
1575{
1577 pbPeerCommitScalar,
1578 32,
1579 pbPeerCommitElement,
1580 64,
1581 pbSharedSecret,
1582 32,
1583 pbScalarSum,
1584 32 );
1585}
#define PRIME_LENGTH_BITS
PCSYMCRYPT_SAE_GROUP_DATA SymCryptSaeFindGroupData(SYMCRYPT_802_11_SAE_GROUP ianaGroup)
SYMCRYPT_ERROR SymCryptModSqrt(_In_ PSYMCRYPT_MODULUS pmMod, _In_ PSYMCRYPT_MODELEMENT peVal, _Out_ PUINT32 puIsQuadraticResidue, _Out_opt_ PSYMCRYPT_MODELEMENT peSqrtArg, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
SYMCRYPT_ERROR SymCrypt802_11SaeCustomInitH2EGeneric(_Out_ PSYMCRYPT_802_11_SAE_CUSTOM_STATE pState, SYMCRYPT_802_11_SAE_GROUP group, _In_reads_(cbPT) PCBYTE pbPT, SIZE_T cbPT, _In_reads_(6) PCBYTE pbMacA, _In_reads_(6) PCBYTE pbMacB, _Inout_updates_opt_(cbRand) PBYTE pbRand, SIZE_T cbRand, _Inout_updates_opt_(cbMask) PBYTE pbMask, SIZE_T cbMask)
SYMCRYPT_ERROR SymCrypt802_11SaeCustomCreatePTGeneric(SYMCRYPT_802_11_SAE_GROUP group, _In_reads_(cbSsid) PCBYTE pbSsid, SIZE_T cbSsid, _In_reads_(cbPassword) PCBYTE pbPassword, SIZE_T cbPassword, _In_reads_opt_(cbPasswordIdentifier) PCBYTE pbPasswordIdentifier, SIZE_T cbPasswordIdentifier, _Out_writes_(cbPT) PBYTE pbPT, SIZE_T cbPT)
struct _SYMCRYPT_SAE_GROUP_DATA * PSYMCRYPT_SAE_GROUP_DATA
SYMCRYPT_ERROR SymCrypt802_11SaeCustomCommitProcess(_In_ PCSYMCRYPT_802_11_SAE_CUSTOM_STATE pState, _In_reads_(32) PCBYTE pbPeerCommitScalar, _In_reads_(64) PCBYTE pbPeerCommitElement, _Out_writes_(32) PBYTE pbSharedSecret, _Out_writes_(32) PBYTE pbScalarSum)
SYMCRYPT_ERROR SymCrypt802_11SaeCustomCommitCreate(_In_ PCSYMCRYPT_802_11_SAE_CUSTOM_STATE pState, _Out_writes_(32) PBYTE pbCommitScalar, _Out_writes_(64) PBYTE pbCommitElement)
SYMCRYPT_ERROR SymCrypt802_11SaeCustomInit(_Out_ PSYMCRYPT_802_11_SAE_CUSTOM_STATE pState, _In_reads_(6) PCBYTE pbMac1, _In_reads_(6) PCBYTE pbMac2, _In_reads_(cbPassword) PCBYTE pbPassword, SIZE_T cbPassword, _Out_opt_ PBYTE pbCounter, _Inout_updates_opt_(32) PBYTE pbRand, _Inout_updates_opt_(32) PBYTE pbMask)
SYMCRYPT_ERROR SymCrypt802_11SaeCustomSetRandMask(_Inout_ PSYMCRYPT_802_11_SAE_CUSTOM_STATE pState, _Inout_updates_opt_(cbRand) PBYTE pbRand, SIZE_T cbRand, _Inout_updates_opt_(cbMask) PBYTE pbMask, SIZE_T cbMask, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
const SYMCRYPT_SAE_GROUP_DATA g_ianaData[]
SYMCRYPT_ERROR SymCrypt802_11SaeCustomCommitCreateGeneric(_In_ PCSYMCRYPT_802_11_SAE_CUSTOM_STATE pState, _Out_writes_(cbCommitScalar) PBYTE pbCommitScalar, SIZE_T cbCommitScalar, _Out_writes_(cbCommitElement) PBYTE pbCommitElement, SIZE_T cbCommitElement)
struct _SYMCRYPT_SAE_GROUP_DATA SYMCRYPT_SAE_GROUP_DATA
const SYMCRYPT_SAE_GROUP_DATA * PCSYMCRYPT_SAE_GROUP_DATA
SYMCRYPT_ERROR SymCryptSswu(_In_ PSYMCRYPT_ECURVE pCurve, _In_ INT32 z, _In_ PSYMCRYPT_MODELEMENT peU, _Out_ PSYMCRYPT_ECPOINT poP, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
SYMCRYPT_ERROR SymCrypt802_11SaeCustomCreatePT(_In_reads_(cbSsid) PCBYTE pbSsid, SIZE_T cbSsid, _In_reads_(cbPassword) PCBYTE pbPassword, SIZE_T cbPassword, _In_reads_opt_(cbPasswordIdentifier) PCBYTE pbPasswordIdentifier, SIZE_T cbPasswordIdentifier, _Out_writes_(64) PBYTE pbPT)
SYMCRYPT_ERROR SymCrypt802_11SaeCustomInitH2E(_Out_ PSYMCRYPT_802_11_SAE_CUSTOM_STATE pState, _In_reads_(64) PCBYTE pbPT, _In_reads_(6) PCBYTE pbMacA, _In_reads_(6) PCBYTE pbMacB, _Inout_updates_opt_(32) PBYTE pbRand, _Inout_updates_opt_(32) PBYTE pbMask)
VOID SymCrypt802_11SaeCustomDestroy(_Inout_ PSYMCRYPT_802_11_SAE_CUSTOM_STATE pState)
VOID SymCrypt802_11SaeGetGroupSizes(SYMCRYPT_802_11_SAE_GROUP group, _Out_opt_ SIZE_T *pcbScalar, _Out_opt_ SIZE_T *pcbPoint)
SYMCRYPT_ERROR SymCrypt802_11SaeCustomCommitProcessGeneric(_In_ PCSYMCRYPT_802_11_SAE_CUSTOM_STATE pState, _In_reads_(cbPeerCommitScalar) PCBYTE pbPeerCommitScalar, SIZE_T cbPeerCommitScalar, _In_reads_(cbPeerCommitElement) PCBYTE pbPeerCommitElement, SIZE_T cbPeerCommitElement, _Out_writes_(cbSharedSecret) PBYTE pbSharedSecret, SIZE_T cbSharedSecret, _Out_writes_(cbScalarSum) PBYTE pbScalarSum, SIZE_T cbScalarSum)
COMPILER_DEPENDENT_UINT64 UINT64
Definition: actypes.h:131
#define index(s, c)
Definition: various.h:29
unsigned int * PUINT32
Definition: basetsd.h:119
#define NULL
Definition: types.h:112
static void cleanup(void)
Definition: main.c:1335
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint index
Definition: glext.h:6031
GLboolean GLuint group
Definition: glext.h:11120
GLdouble GLdouble z
Definition: glext.h:5874
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 * u
Definition: glfuncs.h:240
void SYMCRYPT_CALL SymCryptCallbackFree(void *ptr)
Definition: implglue.c:42
void *SYMCRYPT_CALL SymCryptCallbackAlloc(SIZE_T size)
Definition: implglue.c:37
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Out_opt_
Definition: no_sal2.h:214
#define _Inout_
Definition: no_sal2.h:162
#define _Out_writes_(s)
Definition: no_sal2.h:176
#define _Out_
Definition: no_sal2.h:160
#define _In_reads_opt_(s)
Definition: no_sal2.h:222
#define _In_
Definition: no_sal2.h:158
#define _Out_writes_bytes_(s)
Definition: no_sal2.h:178
#define _Inout_updates_opt_(s)
Definition: no_sal2.h:232
BYTE * PBYTE
Definition: pedump.c:66
BYTE abSeed[SYMCRYPT_LMS_MAX_N]
Definition: sc_lib.h:4735
#define SYMCRYPT_ARRAY_SIZE(_x)
Definition: sc_lib.h:342
UINT32 UINT32 UINT32 UINT32 cbScratch
PSYMCRYPT_MAC_EXPAND_KEY expandKeyFunc
PSYMCRYPT_MAC_RESULT resultFunc
PSYMCRYPT_MAC_APPEND appendFunc
PSYMCRYPT_MAC_INIT initFunc
const PCSYMCRYPT_ECURVE_PARAMS * pCurveParams
const PCSYMCRYPT_MAC * macAlgorithm
SYMCRYPT_802_11_SAE_GROUP group
VOID SYMCRYPT_CALL SymCryptEcurveFree(_Out_ PSYMCRYPT_ECURVE pCurve)
Definition: ecurve.c:657
#define SYMCRYPT_ASSERT(_x)
Definition: symcrypt.h:10807
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptHkdfExpandKey(_Out_ PSYMCRYPT_HKDF_EXPANDED_KEY pExpandedKey, _In_ PCSYMCRYPT_MAC macAlgorithm, _In_reads_(cbIkm) PCBYTE pbIkm, SIZE_T cbIkm, _In_reads_opt_(cbSalt) PCBYTE pbSalt, SIZE_T cbSalt)
Definition: hkdf.c:18
FORCEINLINE VOID SYMCRYPT_CALL SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsNistP384
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptHmacSha256ExpandKey(_Out_ PSYMCRYPT_HMAC_SHA256_EXPANDED_KEY pExpandedKey, _In_reads_opt_(cbKey) PCBYTE pbKey, SIZE_T cbKey)
const PCSYMCRYPT_MAC SymCryptHmacSha256Algorithm
Definition: hmacsha256.c:29
#define SYMCRYPT_STORE_LSBFIRST16(p, v)
Definition: symcrypt.h:306
VOID SYMCRYPT_CALL SymCryptWipe(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
Definition: libmain.c:137
#define SYMCRYPT_LOAD_MSBFIRST64(p)
Definition: symcrypt.h:304
#define SYMCRYPT_HMAC_SHA256_RESULT_SIZE
Definition: symcrypt.h:2856
SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptHkdfDerive(_In_ PCSYMCRYPT_HKDF_EXPANDED_KEY pExpandedKey, _In_reads_opt_(cbInfo) PCBYTE pbInfo, SIZE_T cbInfo, _Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult)
Definition: hkdf.c:106
@ SYMCRYPT_ECPOINT_FORMAT_X
Definition: symcrypt.h:7194
@ SYMCRYPT_ECPOINT_FORMAT_XY
Definition: symcrypt.h:7195
const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsNistP256
const PCSYMCRYPT_MAC SymCryptHmacSha384Algorithm
Definition: hmacsha384.c:31
PSYMCRYPT_ECURVE SYMCRYPT_CALL SymCryptEcurveAllocate(_In_ PCSYMCRYPT_ECURVE_PARAMS pParams, _In_ UINT32 flags)
Definition: ecurve.c:606
VOID SYMCRYPT_CALL SymCryptHmacSha256Result(_Inout_ PSYMCRYPT_HMAC_SHA256_STATE pState, _Out_writes_(SYMCRYPT_HMAC_SHA256_RESULT_SIZE) PBYTE pbResult)
#define SYMCRYPT_STORE_MSBFIRST64(p, v)
Definition: symcrypt.h:312
@ SYMCRYPT_NUMBER_FORMAT_MSB_FIRST
Definition: symcrypt.h:7017
VOID SYMCRYPT_CALL SymCryptHmacSha256Init(_Out_ PSYMCRYPT_HMAC_SHA256_STATE pState, _In_ PCSYMCRYPT_HMAC_SHA256_EXPANDED_KEY pExpandedKey)
SYMCRYPT_ERROR
Definition: symcrypt.h:227
VOID SYMCRYPT_CALL SymCryptHmacSha256Append(_Inout_ PSYMCRYPT_HMAC_SHA256_STATE pState, _In_reads_(cbData) PCBYTE pbData, SIZE_T cbData)
#define SYMCRYPT_MASK32_EQ(_a, _b)
SYMCRYPT_MODELEMENT * PSYMCRYPT_MODELEMENT
PCSYMCRYPT_ECURVE pCurve
SYMCRYPT_MAGIC_FIELD SYMCRYPT_HMAC_SHA256_STATE
#define SYMCRYPT_BYTES_FROM_BITS(bits)
#define SYMCRYPT_MAX(_a, _b)
SYMCRYPT_MAGIC_FIELD SYMCRYPT_HMAC_SHA256_EXPANDED_KEY
SYMCRYPT_ECPOINT * PSYMCRYPT_ECPOINT
PSYMCRYPT_COMMON_HASH_STATE pState
const BYTE * PCBYTE
SYMCRYPT_MODULUS * PSYMCRYPT_MODULUS
SYMCRYPT_INT * PSYMCRYPT_INT
const SYMCRYPT_ECURVE * PCSYMCRYPT_ECURVE
SYMCRYPT_ECURVE * PSYMCRYPT_ECURVE
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_SCALAR_ECURVE_OPERATIONS(_pCurve, _nPoints)
VOID SYMCRYPT_CALL SymCryptEcpointAdd(_In_ PCSYMCRYPT_ECURVE pCurve, _In_ PCSYMCRYPT_ECPOINT poSrc1, _In_ PCSYMCRYPT_ECPOINT poSrc2, _Out_ PSYMCRYPT_ECPOINT poDst, UINT32 flags, _Out_writes_bytes_opt_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ec_dispatch.c:202
UINT32 SYMCRYPT_CALL SymCryptIntGetValueLsbits32(_In_ PCSYMCRYPT_INT piSrc)
Definition: a_dispatch.c:270
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 SymCryptModElementMaskedCopy(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_MODELEMENT peDst, UINT32 mask)
Definition: a_dispatch.c:692
VOID SYMCRYPT_CALL SymCryptIntDivPow2(_In_ PCSYMCRYPT_INT piSrc, SIZE_T exp, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:364
const SYMCRYPT_802_11_SAE_CUSTOM_STATE * PCSYMCRYPT_802_11_SAE_CUSTOM_STATE
struct _SYMCRYPT_802_11_SAE_CUSTOM_STATE * PSYMCRYPT_802_11_SAE_CUSTOM_STATE
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
VOID SymCryptEcpointMaskedCopy(_In_ PCSYMCRYPT_ECURVE pCurve, _In_ PCSYMCRYPT_ECPOINT poSrc, _Out_ PSYMCRYPT_ECPOINT poDst, UINT32 mask)
Definition: ecpoint.c:190
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
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
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
VOID SymCryptModElementCopy(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_MODELEMENT peDst)
Definition: a_dispatch.c:683
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)
VOID SYMCRYPT_CALL SymCryptModNeg(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:895
#define SYMCRYPT_FLAG_MODULUS_PRIME
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
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
@ SYMCRYPT_SAE_GROUP_20
@ SYMCRYPT_SAE_GROUP_19
VOID SYMCRYPT_CALL SymCryptModElementSetValueUint32(UINT32 value, _In_ PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:908
UINT32 SYMCRYPT_CALL SymCryptIntAddUint32(_In_ PCSYMCRYPT_INT piSrc1, UINT32 u32Src2, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:284
PSYMCRYPT_ECPOINT SYMCRYPT_CALL SymCryptEcpointAllocate(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecpoint.c:49
#define SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS(_nDigits)
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
UINT32 SYMCRYPT_CALL SymCryptEcurveDigitsofFieldElement(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecurve.c:682
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
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntAllocate(UINT32 nDigits)
Definition: a_dispatch.c:119
UINT32 SYMCRYPT_CALL SymCryptIntSubUint32(_In_ PCSYMCRYPT_INT piSrc1, UINT32 Src2, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:314
VOID SYMCRYPT_CALL SymCryptModSquare(_In_ PCSYMCRYPT_MODULUS pmMod, _In_ PCSYMCRYPT_MODELEMENT peSrc, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:881
VOID SYMCRYPT_CALL SymCryptEcpointFree(_In_ PCSYMCRYPT_ECURVE pCurve, _Out_ PSYMCRYPT_ECPOINT poDst)
Definition: ecpoint.c:75
PSYMCRYPT_INT SYMCRYPT_CALL SymCryptIntFromModulus(_In_ PSYMCRYPT_MODULUS pmSrc)
Definition: a_dispatch.c:720
#define SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS(_pCurve)
#define SYMCRYPT_FLAG_MODRANDOM_ALLOW_MINUSONE
VOID SYMCRYPT_CALL SymCryptEcpointNegate(_In_ PCSYMCRYPT_ECURVE pCurve, _Inout_ PSYMCRYPT_ECPOINT poSrc, UINT32 mask, _Out_writes_bytes_opt_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: ec_dispatch.c:248
UINT32 SYMCRYPT_CALL SymCryptIntIsEqualUint32(_In_ PCSYMCRYPT_INT piSrc1, _In_ UINT32 u32Src2)
Definition: a_dispatch.c:424
VOID SYMCRYPT_CALL SymCryptIntFree(_Out_ PSYMCRYPT_INT piObj)
Definition: a_dispatch.c:126
VOID SYMCRYPT_CALL SymCryptIntSetValueUint32(UINT32 u32Src, _Out_ PSYMCRYPT_INT piDst)
Definition: a_dispatch.c:230
VOID SYMCRYPT_CALL SymCryptIntToModulus(_In_ PCSYMCRYPT_INT piSrc, _Out_ PSYMCRYPT_MODULUS pmDst, UINT32 averageOperations, UINT32 flags, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:727
UINT32 SYMCRYPT_CALL SymCryptEcurveDigitsofScalarMultiplier(_In_ PCSYMCRYPT_ECURVE pCurve)
Definition: ecurve.c:710
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 SymCryptModElementSetValueNegUint32(UINT32 value, _In_ PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peDst, _Out_writes_bytes_(cbScratch) PBYTE pbScratch, SIZE_T cbScratch)
Definition: a_dispatch.c:922
#define SYMCRYPT_SCRATCH_BYTES_FOR_GETSET_VALUE_ECURVE_OPERATIONS(_pCurve)
PSYMCRYPT_MODULUS SYMCRYPT_CALL SymCryptModulusAllocate(UINT32 nDigits)
Definition: a_dispatch.c:587
VOID SYMCRYPT_CALL SymCryptModulusFree(_Out_ PSYMCRYPT_MODULUS pmObj)
Definition: a_dispatch.c:594
VOID SYMCRYPT_CALL SymCryptModElementFree(_In_ PCSYMCRYPT_MODULUS pmMod, _Out_ PSYMCRYPT_MODELEMENT peObj)
Definition: a_dispatch.c:649
#define SYMCRYPT_SAE_MAX_HMAC_OUTPUT_SIZE_BYTES
#define SYMCRYPT_FLAG_DATA_PUBLIC
PSYMCRYPT_MODELEMENT SYMCRYPT_CALL SymCryptModElementAllocate(_In_ PCSYMCRYPT_MODULUS pmMod)
Definition: a_dispatch.c:642
#define SYMCRYPT_SAE_MAX_EC_POINT_SIZE_BYTES
#define SYMCRYPT_SCRATCH_BYTES_FOR_MODEXP(_nDigits)
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
enum _SYMCRYPT_802_11_SAE_GROUP SYMCRYPT_802_11_SAE_GROUP
int32_t INT32
Definition: typedefs.h:58
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t UINT32
Definition: typedefs.h:59
unsigned char BYTE
Definition: xxhash.c:193