Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/symcrypt/inc/symcrypt_low_level.h
15010 views
1
//
2
// SymCrypt_low_level.h
3
//
4
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5
//
6
7
#pragma once
8
9
10
#ifdef __cplusplus
11
extern "C" {
12
#endif
13
14
//=======================================================================================
15
// WARNING: The low-level APIs are not stable, and can change from release to release.
16
// The low-level APIs are only provided for certain exceptional use cases.
17
// All aspects of the low-level API can change in any release.
18
// Users are strongly advised to only rely on the API surface defined in symcrypt.h
19
//=======================================================================================
20
21
22
//
23
// Low level asymmetric algorithm API. This is not to be used by external callers.
24
//
25
26
/**************************************************************************************************
27
Low-level Integer API
28
**************************************************************************************************
29
The low-level API allows manipulation of arbitrarily large integers.
30
31
The internal representation of large integers is not fixed. It depends on CPU architecture and
32
on the CPU features available on the exact CPU stepping the current software is running on.
33
In other words, it can change between different executions of the same binary.
34
Therefore it is critical that callers refrain from making assumptions about the internal
35
data format used. SymCrypt numbers should only be manipulated through the SymCrypt
36
API.
37
38
The low-level API allows the caller to allocate the necessary memory for all objects.
39
This is typically necessary for high-IRQL level callers, callers running in low-memory
40
environments, and high-performance scenarios where memory has to be pre-allocated.
41
SymCrypt also provides routines for allocating objects, which makes the API easier
42
to use. The caller has to provide the allocation functions that SymCrypt uses.
43
44
Internal data representation, and consequently the size of objects, can depend on the
45
exact CPU stepping the code is running on.
46
For robustness, the allocation size requirements are compile-time properties;
47
they vary per CPU architecture but do not depend on the exact available CPU features.
48
49
General rules:
50
The functions in the low-level API can impose requirements on their inputs. It is imperative that
51
these requirements are satisfied for every call; failing to satisfy the requirements leads to undefined
52
behaviour, including bugchecks, access violations, wrong results, or sometimes even the right result.
53
CHKed versions of the library add more low-level consistency checks; all binaries should be tested
54
with a CHKed version of the library to detect any errors that might go unnoticed on FRE versions.
55
56
Scratch space:
57
Many functions in the API require temporary storage for intermediate results.
58
Some function simply allocate the necessary memory using the caller-provided allocation routines.
59
Other low-level functions are so fast that the overhead of the allocations would significantly slow
60
down the computations. These functions require the caller to allocate the memory; this memory
61
is called the scratch space.
62
63
For each function that requires scratch space, there is a macro that determines how much scratch space
64
must be provided. This macro is a compile-time function of its arguments; if the parameters to the macro
65
are compile-time constants, then the result is also a compile-time constant. Therefore that
66
the macro can be used for statically sizing arrays.
67
The scratch space macros are all non-decreasing in each argument.
68
Callers that perform multiple operations can use a single scratch space, sized for the largest
69
argument(s) used. Note that the SYMCRYPT_C_MAX macro implements a compile-time MAX function suitable
70
for combining different scratch space sizes at compile time.
71
72
The scratch space is always passed as a pair or arguments: (pbScratch, cbScratch).
73
cbScratch needs to be at least as large as the macro definition requires, but may be larger.
74
75
Functions that take scratch parameters do not require memory allocation, and will not fail due to
76
low-memory conditions.
77
All functions that use memory allocation will return an error indication if a necessary memory
78
allocation fails. These functions return an error code, or an object pointer which will be NULL if
79
the allocation fails.
80
Functions that do not return an error code or object pointer do not use memory allocation.
81
82
SymCrypt uses several implementation techniques to minimize the cost of the scratch space parameters.
83
This is necessary because the cost of the parameter passing by itself is significant in scenarios
84
such as elliptic-curve operations.
85
In a FRE build, some functions will ignore the cbScratch parameter and simply assume they get enough space;
86
in this case the SymCrypt may provide an inline-able function that allow the compiler to optimize the cbScratch parameter
87
away, completely removing it from the actual code.
88
In environments where some functions don't need any scratch space, similar optimizations are possible for the
89
pbScratch parameter.
90
91
Scratch and object buffers must all be aligned to SYMCRYPT_ALIGN.
92
93
*/
94
95
//
96
// General flags
97
//
98
// SYMCRYPT_FLAG_DATA_PUBLIC is used to signal that the data being processed is public, and does not have
99
// to be protected from side-channel attacks.
100
#define SYMCRYPT_FLAG_DATA_PUBLIC (0x01)
101
102
/*
103
INTEGERS
104
105
Integers are internally represented as a sequence of Digits. An INT object with n digits can store
106
numbers up to (but not including) R^n where R is the _radix_ of the representation.
107
108
The radix R, as well as the size and format of a Digit, are internal to the library,
109
and can depend on CPU architecture, CPU stepping and other run-time decisions. Therefore, callers
110
need to be especially careful not to make any assumptions about the size of a digit, or the number
111
of digits needed for any particular computation.
112
113
At the same time, most INT operations are defined in terms of Digit sizes, so the caller has to
114
be aware of digits. This becomes important in the following example. Suppose the radix R =2^256,
115
and a caller wants to multiply two 384-bit numbers. It takes 2 digits to store a 384-bit number.
116
The caller knows that the product is 768 bits, which can fit in 3 digits. So the caller might try
117
to multiply two 2-digit numbers into a 3-digit result, which will not work as the result is 4 digits.
118
119
For an INT object of n digits we call the value R^n the capacity of the object. It is the upper bound of
120
the values that can be stored in the object.
121
122
Additionally, there is a maximum number of bits for any integer value that the library supports (2^20 bits
123
in the current version). This bound is used to ensure that no object sizes and scratch space computations
124
have a value of magnitude more than 32 bits. Note that the computed upper bounds are very loose and the
125
actual values are much smaller.
126
127
Attempts to create objects larger than this bound will result in NULL being returned. Callers either have
128
to ensure they do not exceed the bounds, or check that create objects are not NULL before using them. The
129
rationale behind this approach is to avoid any potential route for malicious inputs to trigger DoS by
130
taking excessive CPU time which would be indistinguishable from an application hang.
131
132
133
Digit size and radix can vary widely; on some CPU steppings the library might use a digit that contains
134
128 bits are requires 16 bytes of memory, on another CPU stepping it might use a digit that contains
135
416 bits and uses 64 bytes of memory.
136
137
SAL annotations:
138
Because the different run-time selected implementations underneath this API might use
139
different size memory buffers for any one operation, fully accurate SAL annotations are not possible as SAL only
140
performs static analysis.
141
Furthermore, adding size parameters to every function would add too much overhead, and sizes are often passed
142
implicitly. Together with the fact that the same API can be implemented by different implementations, this means
143
that it isn't possible to write the actual size used in a form that SAL can understand.
144
Instead we use the following conventions:
145
- Pointers to SYMCRYPT_* objects can only be created with functions that provide the right memory buffer size.
146
- We annotate each object-pointer with _In_ our _Out_. The SAL engine treats this as just a read/write to
147
a single object at the pointer location
148
- The CHKed version of SymCrypt adds run-time checking that the various size parameters are correct.
149
This allows us to have both high performance and good checking of our memory management.
150
151
API rationale:
152
One important choice in this API is whether to pass a (ptr,len) for each INT or just a pointer.
153
We investigated this issue. The ptr-based API means that there are fewer parameters to pass around,
154
and generally makes the API simpler. The downside of a ptr-based API is that each INT object has some overhead
155
and this makes arrays of large integers less efficient, especially since the overhead can be a whole alignment
156
block.
157
The problem with the (ptr,len) format is that it isn't clear what length measure to use.
158
Using the bitsize is inefficient; the internal format might store 29 bits of the number in each 32-bit word,
159
and that means that the code would have to divide the bitsize by 29 just to find the size of the number.
160
Division is slow, and therefore this is not a good choice.
161
Another idea is to have the len parameter be the length of the INT object, in bytes.
162
But some APIs get really messy. For example, we need an API function to do a multiplication of two same-sized
163
numbers into a double-sized number. This is such a common operation that we want a separate function for it.
164
But the storage size of the result might not be twice the storage size of the inputs; if each number has some
165
fixed overhead then the output object might be smaller than the two times the size of the input objects.
166
This makes it impossible to write suitable SAL annotations.
167
For this reason, we use a ptr-based API for integers.
168
169
Most crypto algorithms that wish to store arrays of values actually want to store arrays of elements in a
170
ring modulo an modulus. And for modular operations the caller is already passing the modulus separately, so
171
there isn't any need to store per-object size information. The API is designed to allow the ModElement for bitsize
172
B to be smaller than an INT for bitsize B so that implementations can choose to not store any length information in
173
a ModElement object.
174
*/
175
176
//========================================================================
177
//========================================================================
178
// Main schema for object creation, deletion, and management (low - level calls).
179
//
180
// The following are descriptions of some of the generic functions specifically
181
// modified for the INT, DIVISOR, MODULUS, and MODELEMENT objects.
182
183
//
184
// PSYMCRYPT_XXX
185
// SYMCRYPT_CALL
186
// SymCryptXxxCreate(
187
// _Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,
188
// SIZE_T cbBuffer,
189
// UINT32 nDigits );
190
// Create an XXX object from the provided (pbBuffer, cbBuffer) space.
191
// The object will be able to store values up to R^nDigits where R is the digit radix.
192
// Requirement:
193
// - 1 <= nDigits <= SymCryptDigitsFromBits(SYMCRYPT_INT_MAX_BITS)
194
// If the value is outside these bounds it will return NULL
195
// - cbBuffer >= SymCryptSizeofXxxFromDigits( nDigits )
196
// - (pbBuffer,cbBuffer) memory must be exclusively used by this object.
197
// The last requirement ensures that all objects are non-overlapping (except for API functions
198
// that explicitly create overlapping objects).
199
// All parameters are published.
200
// It is always safe to choose
201
// cbBuffer = SYMCRYPT_SIZEOF_XXX_FROM_BITS( nBits )
202
// nDigits = SymCryptDigitsFromBits( nBits )
203
// if the caller wants to be able to store numbers up to 2^nBits. However, it is frequently more
204
// efficient to use cbBuffer = SymCryptSizeofXxxFromDigits( nDigits ) as that gives the exact size for the
205
// current CPU stepping rather than the compile-time largest size that might be needed on any stepping.
206
//
207
// PSYMCRYPT_XXX
208
// SYMCRYPT_CALL
209
// SymCryptXxxRetrieveHandle( _In_ PBYTE pbBuffer );
210
// Retrieve the object's handle from the pointer to the memory space in which the object was created via
211
// a call to SymCryptXxxCreate. This function allows callers to tightly store arrays of objects without having
212
// to keep track of each object handle.
213
// Requirement:
214
// - A call to SymCryptXxxRetrieveHandle( pbBuffer1 ) must be preceded by at least one call to
215
// SymCryptXxxCreate( pbBuffer2, cbBuffer2, nDigits ) with ( pbBuffer1 == pbBuffer2 )
216
// If the requirement is not satisfied the result is undefined.
217
//
218
// #define SYMCRYPT_SIZEOF_XXX_FROM_BITS( nBits ) ...
219
// Returns a memory size that is always sufficient to create an XXX object that can handle
220
// values of size nBits bits, irrespective of the run-time decision of digit size.
221
// This is a non-decreasing compile-time function of its inputs, suitable for computing static memory allocations.
222
// It is always true that
223
// SYMCRYPT_SIZEOF_XXX_FROM_BITS( n ) >= SymCryptSizeofXxxFromDigits( SymCryptDigitsFromBits( n ) )
224
// which guarantees that the n-bit XXX can be stored in a memory area of SYMCRYPT_SIZEOF_XXX_FROM_BITS(n) bytes.
225
// Warning: It is possible that
226
// SYMCRYPT_SIZEOF_XXX_FROM_BITS( n+m ) < SymCryptSizeofXxxFromDigits( SymCryptDigitsFromBits( n ) + SymCryptDigitsFromBits( m ) )
227
// for some inputs n and m. This is easy to see if you choose n = m = 1; each represents a 1-digit value, but an n+m bit (i.e. a 2-bit ) value is
228
// also 1 digit.
229
// In particular, you cannot use SYMCRYPT_SIZEOF_XXX_FROM_BITS( n + m ) to compute the size
230
// necessary to store the product of two numbers with bitsize n and m respectively.
231
// It is guaranteed that
232
// SymCryptSizeofXxxFromDigits( SymCryptDigitsFromBits( n ) + SymCryptDigitsFromBits( m ) ) <=
233
// SYMCRYPT_SIZEOF_XXX_FROM_BITS( n ) + SYMCRYPT_SIZEOF_XXX_FROM_BITS( m )
234
// This is the proper way to statically compute the size needed to store the product of an n- and m-bit value.
235
//
236
// UINT32
237
// SYMCRYPT_CALL
238
// SymCryptSizeofXxxFromDigits( UINT32 nDigits );
239
// Memory size that is sufficient to store an XXX object with nDigits digits.
240
// This is a runtime function as the # digits and size of a digit are run-time decision that depend on the CPU stepping.
241
// Requirement:
242
// - 1 <= nDigits <= SymCryptDigitsFromBits(SYMCRYPT_INT_MAX_BITS)
243
// If the value is outside these bounds the returned value will be 0 indicating failure.
244
// This function is has the following property:
245
// SymCryptSizeofXxxFromDigits( a + b ) <= SymCryptSizeofXxxFromDigits( a ) + SymCryptSizeofXxxFromDigits( b )
246
// for all a and b.
247
//
248
// UINT32
249
// SYMCRYPT_CALL
250
// SymCryptXxxBitsizeOfObject( PCSYMCRYPT_XXX pObj )
251
// Return the number of bits of the object.
252
//
253
// UINT32
254
// SYMCRYPT_CALL
255
// SymCryptXxxDigitsizeOfObject( PCSYMCRYPT_XXX pObj )
256
// Return the number of digits of the object.
257
//
258
259
//==============================================================================================
260
// Object types for low-level API
261
//
262
// SYMCRYPT_INT integer in range 0..N for some N
263
// SYMCRYPT_DIVISOR an integer > 0 that can be used to divide with.
264
// SYMCRYPT_MODULUS a value M > 1 to use in modulo-M computations
265
// SYMCRYPT_MODELEMENT An element in a modulo-M ring.
266
// SYMCRYPT_ECPOINT A point on an elliptic curve.
267
//
268
// See symcrypt_internal.h for definitions.
269
//
270
271
//========================================================================
272
//========================================================================
273
// General functions for integers
274
//
275
276
UINT32
277
SymCryptDigitsFromBits( UINT32 nBits );
278
//
279
// Returns the # digits needed to store values (INT, DIVISOR, MODULUS, MODELEMENT)
280
// in the range 0..(2^nBits - 1).
281
//
282
// Remarks:
283
// If nBits==0 the returned number is 1.
284
//
285
// If nBits exceeds SYMCRYPT_INT_MAX_BITS the function will return 0 to indicate an object with
286
// this many bits is not supported.
287
//
288
// This is a run-time decision; the return value can depend on the exact CPU stepping
289
// the program is running on, or run-time configurations.
290
// For a and b in the range 0..SYMCRYPT_INT_MAX_BITS, it is always true that
291
// SymCryptDigitsFromBits( a + b ) <= SymCryptDigitsFromBits( a ) + SymCryptDigitsFromBits( b )
292
//
293
294
//========================================================================
295
// INT objects
296
//
297
298
PSYMCRYPT_INT
299
SYMCRYPT_CALL
300
SymCryptIntAllocate( UINT32 nDigits );
301
302
VOID
303
SYMCRYPT_CALL
304
SymCryptIntFree( _Out_ PSYMCRYPT_INT piObj );
305
306
#define SYMCRYPT_SIZEOF_INT_FROM_BITS( _bitsize ) SYMCRYPT_INTERNAL_SIZEOF_INT_FROM_BITS( _bitsize )
307
308
UINT32
309
SYMCRYPT_CALL
310
SymCryptSizeofIntFromDigits( UINT32 nDigits );
311
312
PSYMCRYPT_INT
313
SYMCRYPT_CALL
314
SymCryptIntCreate(
315
_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,
316
SIZE_T cbBuffer,
317
UINT32 nDigits );
318
319
VOID
320
SYMCRYPT_CALL
321
SymCryptIntWipe( _Out_ PSYMCRYPT_INT piObj );
322
323
VOID
324
SYMCRYPT_CALL
325
SymCryptIntCopy(
326
_In_ PCSYMCRYPT_INT piSrc,
327
_Out_ PSYMCRYPT_INT piDst ); // **** Documentation lacking: requires same size
328
329
VOID
330
SYMCRYPT_CALL
331
SymCryptIntMaskedCopy(
332
_In_ PCSYMCRYPT_INT piSrc,
333
_Inout_ PSYMCRYPT_INT piDst,
334
UINT32 mask );
335
336
VOID
337
SYMCRYPT_CALL
338
SymCryptIntConditionalCopy(
339
_In_ PCSYMCRYPT_INT piSrc,
340
_Inout_ PSYMCRYPT_INT piDst,
341
UINT32 cond );
342
343
VOID
344
SYMCRYPT_CALL
345
SymCryptIntConditionalSwap(
346
_Inout_ PSYMCRYPT_INT piSrc1,
347
_Inout_ PSYMCRYPT_INT piSrc2,
348
UINT32 cond );
349
350
UINT32
351
SYMCRYPT_CALL
352
SymCryptIntBitsizeOfObject( _In_ PCSYMCRYPT_INT piSrc );
353
354
UINT32
355
SYMCRYPT_CALL
356
SymCryptIntDigitsizeOfObject( _In_ PCSYMCRYPT_INT piSrc );
357
358
//========================================================================
359
// DIVISOR objects
360
//
361
362
PSYMCRYPT_DIVISOR
363
SYMCRYPT_CALL
364
SymCryptDivisorAllocate( UINT32 nDigits );
365
366
VOID
367
SYMCRYPT_CALL
368
SymCryptDivisorFree( _Out_ PSYMCRYPT_DIVISOR pdObj );
369
370
#define SYMCRYPT_SIZEOF_DIVISOR_FROM_BITS( _bitsize ) SYMCRYPT_INTERNAL_SIZEOF_DIVISOR_FROM_BITS( _bitsize )
371
372
UINT32
373
SYMCRYPT_CALL
374
SymCryptSizeofDivisorFromDigits( UINT32 nDigits );
375
376
PSYMCRYPT_DIVISOR
377
SYMCRYPT_CALL
378
SymCryptDivisorCreate(
379
_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,
380
SIZE_T cbBuffer,
381
UINT32 nDigits );
382
383
VOID
384
SYMCRYPT_CALL
385
SymCryptDivisorWipe( _Out_ PSYMCRYPT_DIVISOR pdObj );
386
387
VOID
388
SymCryptDivisorCopy(
389
_In_ PCSYMCRYPT_DIVISOR pdSrc,
390
_Out_ PSYMCRYPT_DIVISOR pdDst );
391
392
UINT32
393
SYMCRYPT_CALL
394
SymCryptDivisorDigitsizeOfObject( _In_ PCSYMCRYPT_DIVISOR pdSrc );
395
396
//========================================================================
397
// MODULUS objects
398
//
399
400
PSYMCRYPT_MODULUS
401
SYMCRYPT_CALL
402
SymCryptModulusAllocate( UINT32 nDigits );
403
404
VOID
405
SYMCRYPT_CALL
406
SymCryptModulusFree( _Out_ PSYMCRYPT_MODULUS pmObj );
407
408
#define SYMCRYPT_SIZEOF_MODULUS_FROM_BITS( _bitsize ) SYMCRYPT_INTERNAL_SIZEOF_MODULUS_FROM_BITS( _bitsize )
409
410
UINT32
411
SYMCRYPT_CALL
412
SymCryptSizeofModulusFromDigits( UINT32 nDigits );
413
414
PSYMCRYPT_MODULUS
415
SYMCRYPT_CALL
416
SymCryptModulusCreate(
417
_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,
418
SIZE_T cbBuffer,
419
UINT32 nDigits );
420
421
VOID
422
SYMCRYPT_CALL
423
SymCryptModulusWipe( _Out_ PSYMCRYPT_MODULUS pmObj );
424
425
VOID
426
SymCryptModulusCopy(
427
_In_ PCSYMCRYPT_MODULUS pmSrc,
428
_Out_ PSYMCRYPT_MODULUS pmDst );
429
430
UINT32
431
SYMCRYPT_CALL
432
SymCryptModulusDigitsizeOfObject( _In_ PCSYMCRYPT_MODULUS pmSrc );
433
434
//========================================================================
435
// MODELEMENT objects are treated slightly differently because it does not store its own size.
436
// This allows a MODELEMENT to be more compact which makes large arrays of ModElements more efficient
437
// and avoids checking that ModElements have the same size.
438
// All operations require a modulus to be passed.
439
//
440
441
PSYMCRYPT_MODELEMENT
442
SYMCRYPT_CALL
443
SymCryptModElementAllocate( _In_ PCSYMCRYPT_MODULUS pmMod );
444
445
VOID
446
SYMCRYPT_CALL
447
SymCryptModElementFree(
448
_In_ PCSYMCRYPT_MODULUS pmMod, // only used to determine the digit size of peObj.
449
_Out_ PSYMCRYPT_MODELEMENT peObj );
450
451
#define SYMCRYPT_SIZEOF_MODELEMENT_FROM_BITS( _bitsize ) SYMCRYPT_INTERNAL_SIZEOF_MODELEMENT_FROM_BITS( _bitsize )
452
453
UINT32
454
SYMCRYPT_CALL
455
SymCryptSizeofModElementFromModulus( PCSYMCRYPT_MODULUS pmMod );
456
457
PSYMCRYPT_MODELEMENT
458
SYMCRYPT_CALL
459
SymCryptModElementCreate(
460
_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,
461
SIZE_T cbBuffer,
462
_In_ PCSYMCRYPT_MODULUS pmMod );
463
464
VOID
465
SYMCRYPT_CALL
466
SymCryptModElementWipe(
467
_In_ PCSYMCRYPT_MODULUS pmMod,
468
_Out_ PSYMCRYPT_MODELEMENT peDst );
469
470
VOID
471
SymCryptModElementCopy(
472
_In_ PCSYMCRYPT_MODULUS pmMod,
473
_In_ PCSYMCRYPT_MODELEMENT peSrc,
474
_Out_ PSYMCRYPT_MODELEMENT peDst );
475
476
VOID
477
SymCryptModElementMaskedCopy(
478
_In_ PCSYMCRYPT_MODULUS pmMod,
479
_In_ PCSYMCRYPT_MODELEMENT peSrc,
480
_Out_ PSYMCRYPT_MODELEMENT peDst,
481
UINT32 mask );
482
483
VOID
484
SymCryptModElementConditionalSwap(
485
_In_ PCSYMCRYPT_MODULUS pmMod,
486
_Inout_ PSYMCRYPT_MODELEMENT peData1,
487
_Inout_ PSYMCRYPT_MODELEMENT peData2,
488
_In_ UINT32 cond );
489
490
//========================================================================
491
// ECURVE objects
492
493
BOOLEAN
494
SYMCRYPT_CALL
495
SymCryptEcurveBufferSizesFromParams(
496
_In_ PCSYMCRYPT_ECURVE_PARAMS pParams,
497
_Out_ SIZE_T * pcbCurve,
498
_Out_ SIZE_T * pcbScratch );
499
//
500
// This call computes the memory size necessary to create the ECURVE object described by pParams,
501
// including the amount of scratch space needed for the operation.
502
//
503
// Returns FALSE if the given parameters are deemed invalid.
504
//
505
506
PSYMCRYPT_ECURVE
507
SYMCRYPT_CALL
508
SymCryptEcurveCreate(
509
_In_ PSYMCRYPT_ECURVE_PARAMS pParams,
510
_In_ UINT32 flags,
511
_Out_writes_bytes_( cbCurve ) PBYTE pbCurve,
512
SIZE_T cbCurve,
513
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
514
SIZE_T cbScratch );
515
//
516
// Use caller-allocated memory to create an ECURVE object which
517
// is defined by the parameters in pParams.
518
//
519
// - pParams: parameters that define the curve
520
// - flags: Not used, must be zero.
521
// - pbCurve: caller-allocated memory region to hold the curve object
522
// - cbCurve: size of memory region to hold the curve object
523
// - pbScratch: caller-allocated memory region used as scratch space to create the curve
524
// - cbScratch: size of scratch space memory region
525
//
526
// Caller should use SymCryptSizeofEcurveBuffersFromParams to determine the necessary sizes for
527
// pbCurve and pbScratch. These buffers must be SYMCRYPT_ALIGNed.
528
//
529
// Future versions might use the flags to enable different features/tradeoffs.
530
// There are a number of interesting memory/speed/pre-computation cost trades that can be made.
531
// For example, pre-computing multiples of the distinguished point, or (parallel?) pre-computation
532
// of (r, rG) pairs for random r values.
533
//
534
// This function applies limited validation of the pParams. The validation is intended to eliminate
535
// the threat of denial-of-service when hostile parameters are presented. It does not ensure that
536
// the parameters make sense, define a proper curve, or that any elliptic-curve operations made on
537
// the curve built from these parameters will fail, succeed or provide any security.
538
// The only guarantee provided for invalid parameters is that all operations on this curve will
539
// not crash and will return in some reasonable amount of time.
540
//
541
// Returns NULL if the given memory regions are not large enough or the
542
// parameters are deemed invalid. If the return value is not NULL, then
543
// pbCurve buffer must later be wiped with SymCryptWipe(). And as with all
544
// pbScratch buffers, it is the caller's responsibility to wipe after
545
// completing all operations that require scratch space.
546
//
547
548
//========================================================================
549
// ECPOINT objects' API is slightly different than the above API schema in the sense that they
550
// take as input an ECURVE object pointer instead of the number of digits.
551
//
552
553
PSYMCRYPT_ECPOINT
554
SYMCRYPT_CALL
555
SymCryptEcpointAllocate( _In_ PCSYMCRYPT_ECURVE pCurve );
556
557
VOID
558
SYMCRYPT_CALL
559
SymCryptEcpointFree(
560
_In_ PCSYMCRYPT_ECURVE pCurve,
561
_Out_ PSYMCRYPT_ECPOINT poDst );
562
563
UINT32
564
SYMCRYPT_CALL
565
SymCryptSizeofEcpointFromCurve( PCSYMCRYPT_ECURVE pCurve );
566
567
PSYMCRYPT_ECPOINT
568
SYMCRYPT_CALL
569
SymCryptEcpointCreate(
570
_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,
571
SIZE_T cbBuffer,
572
_In_ PCSYMCRYPT_ECURVE pCurve );
573
// The above can take as input a pointer to a curve that has only the FMod, cbModElement, and the
574
// eformat fields set
575
576
PSYMCRYPT_ECPOINT
577
SYMCRYPT_CALL
578
SymCryptEcpointRetrieveHandle( _In_ PBYTE pbBuffer );
579
580
VOID
581
SYMCRYPT_CALL
582
SymCryptEcpointWipe(
583
_In_ PCSYMCRYPT_ECURVE pCurve,
584
_Out_ PSYMCRYPT_ECPOINT poDst );
585
586
VOID
587
SymCryptEcpointCopy(
588
_In_ PCSYMCRYPT_ECURVE pCurve,
589
_In_ PCSYMCRYPT_ECPOINT poSrc,
590
_Out_ PSYMCRYPT_ECPOINT poDst );
591
592
VOID
593
SymCryptEcpointMaskedCopy(
594
_In_ PCSYMCRYPT_ECURVE pCurve,
595
_In_ PCSYMCRYPT_ECPOINT poSrc,
596
_Out_ PSYMCRYPT_ECPOINT poDst,
597
UINT32 mask );
598
599
600
//========================================
601
// Integer operations
602
//
603
604
SYMCRYPT_ERROR
605
SYMCRYPT_CALL
606
SymCryptIntCopyMixedSize(
607
_In_ PCSYMCRYPT_INT piSrc,
608
_Out_ PSYMCRYPT_INT piDst );
609
//
610
// Dst = Src, but allows Dst and Src to have different # digits.
611
//
612
// Copy the value from piSrc to piDst.
613
// Returns success if Src < R^Dst.nDigits
614
// If Src >= R^Dst.nDigits then the value in Src is published and an error is returned.
615
// Warning: it is not side-channel safe to use this function with a Src value that can't fit in Dst.
616
// Src and Dst may be the same object.
617
//
618
619
UINT32
620
SYMCRYPT_CALL
621
SymCryptIntBitsizeOfValue( _In_ PCSYMCRYPT_INT piSrc );
622
//
623
// Returns the number of bits necessary to store the value of Src.
624
//
625
// Let V be the value of Src.
626
// Then this function returns
627
// 0 if Src == 0
628
// 1 + floor( log(Src)/log(2) ) if V > 0
629
// Note that there is no defined relationship between the result of this function and the bitsize used to allocate Src.
630
// Digits can be large, so the value Src might be able to store values much larger than 2^b where b is the bitsize
631
// used when creating Src.
632
// This function is side-channel safe, and as a result might be slower than expected.
633
//
634
635
636
VOID
637
SYMCRYPT_CALL
638
SymCryptIntSetValueUint32(
639
UINT32 u32Src,
640
_Out_ PSYMCRYPT_INT piDst );
641
//
642
// Dst = Src
643
// This always succeeds as R >= 2^32 on all implementations.
644
//
645
646
VOID
647
SYMCRYPT_CALL
648
SymCryptIntSetValueUint64(
649
UINT64 u64Src,
650
_Out_ PSYMCRYPT_INT piDst );
651
//
652
// Dst = Src
653
// This always succeeds as R >= 2^64 on all implementations.
654
//
655
656
657
//========================================================================================
658
// Read/write INTegers in defined formats
659
//
660
661
SYMCRYPT_ERROR
662
SYMCRYPT_CALL
663
SymCryptIntSetValue(
664
_In_reads_bytes_(cbSrc) PCBYTE pbSrc,
665
SIZE_T cbSrc,
666
SYMCRYPT_NUMBER_FORMAT format,
667
_Out_ PSYMCRYPT_INT piDst );
668
//
669
// Set the value of an INT object from an array of bytes
670
//
671
// (pbSrc,cbSrc): buffer that contains the bytes that encode the value in the specified format.
672
// format: specifies the format of the pbBytes/cbBytes buffer.
673
// Dst : INT object that receives the value; must previously have been created/allocated.
674
//
675
// Return value:
676
// If the value encoded in the (pbSrc,cbSrc) buffer fits in Dst, then the
677
// function succeeds. If the value does not fit, then the function
678
// returns an error. Note that the error condition is only dependent on the value in the input,
679
// and not on how many bytes are in the input. Importing a very large (pbSrc,cbSrc) buffer
680
// into a small piDst is fine as long as the value fits in the number (i.e. enough of the most significant
681
// bytes in the buffer are zero).
682
//
683
// Warning:
684
// Error return values are always published, so if this function fails it is visible to the attacker.
685
//
686
// Rationale:
687
// Because the size of a digit can be any size (even odd) there are always scenarios in which the
688
// caller can provide an input that is too large for the INT to store. (Restricting only the size of
689
// the input buffer is not sufficient.) And if we have to handle this
690
// in one case, we might as well handle it in all cases.
691
//
692
693
SYMCRYPT_ERROR
694
SYMCRYPT_CALL
695
SymCryptIntGetValue(
696
_In_ PCSYMCRYPT_INT piSrc,
697
_Out_writes_bytes_( cbDst) PBYTE pbDst,
698
SIZE_T cbDst,
699
SYMCRYPT_NUMBER_FORMAT format );
700
//
701
// Convert a value from the internal number representation to a byte array.
702
//
703
// Src is the number whose value is to be stored in a byte array
704
// (pbDst, cbDst) the destination buffer
705
// format: the destination format.
706
// Return value: if the value of Src when encoded in the format fits in the output buffer then the function succeeds.
707
// If the encoded value does not fit, the function returns an error. (Note: All errors are published.)
708
//
709
710
UINT32
711
SYMCRYPT_CALL
712
SymCryptIntGetValueLsbits32( _In_ PCSYMCRYPT_INT piSrc );
713
//
714
// Returns Src mod 2^32
715
//
716
// Usecase: there are many number-theoretic algorithms where the algorithm
717
// depends on (n mod 8) or similar values.
718
//
719
720
UINT64
721
SYMCRYPT_CALL
722
SymCryptIntGetValueLsbits64( _In_ PCSYMCRYPT_INT piSrc );
723
//
724
// Returns Src mod 2^64
725
//
726
// Usecase: RSA public exponents can be 64 bits, and validating that
727
// a candidate prime is suitable uses this function
728
//
729
730
UINT32
731
SYMCRYPT_CALL
732
SymCryptIntIsEqualUint32(
733
_In_ PCSYMCRYPT_INT piSrc1,
734
_In_ UINT32 u32Src2 );
735
//
736
// Returns a mask value which is 0xffffffff if Src1 = Src2 and 0 otherwise.
737
//
738
739
UINT32
740
SYMCRYPT_CALL
741
SymCryptIntIsEqual(
742
_In_ PCSYMCRYPT_INT piSrc1,
743
_In_ PCSYMCRYPT_INT piSrc2 );
744
//
745
// Returns a mask value which is 0xffffffff if Src1 = Src2 and 0 otherwise.
746
//
747
// Note that Src1 and Src2 can be of different sizes.
748
//
749
750
UINT32
751
SYMCRYPT_CALL
752
SymCryptIntIsLessThan(
753
_In_ PCSYMCRYPT_INT piSrc1,
754
_In_ PCSYMCRYPT_INT piSrc2 );
755
//
756
// Returns a mask value which is 0xffffffff if Src1 < Src2 and 0 otherwise.
757
//
758
// Note that a <= b is equivalent to NOT( b < a ) so all possible comparisons
759
// can be made using the < and = comparison primitive.
760
//
761
762
763
//=============================================================
764
// Addition & subtraction
765
// For all addition and subtraction operations, the destination may be
766
// the same object as one of the inputs if the other requirements of the function
767
// allow that.
768
//
769
770
UINT32
771
SYMCRYPT_CALL
772
SymCryptIntAddUint32(
773
_In_ PCSYMCRYPT_INT piSrc1,
774
UINT32 u32Src2,
775
_Out_ PSYMCRYPT_INT piDst );
776
//
777
// Dst = Src1 + Src2.
778
// Requirement: Dst.nDigits == Src1.nDigits
779
// If the result is larger than the capacity of Dst, then
780
// Dst is set to the result minus the capacity and the value 1 is returned.
781
// Otherwise the Dst is set to the sum and the value 0 is returned.
782
// The return value is thus a carry output of the addition.
783
//
784
785
UINT32
786
SYMCRYPT_CALL
787
SymCryptIntAddSameSize(
788
_In_ PCSYMCRYPT_INT piSrc1,
789
_In_ PCSYMCRYPT_INT piSrc2,
790
_Out_ PSYMCRYPT_INT piDst );
791
//
792
// Dst = Src1 + Src2.
793
// Requirement: Src1.nDigits == Src2.nDigits == Dst.nDigits
794
// In more detail:
795
// if Src1 + Src2 < Dst.capacity:
796
// Dst = Src1 + Src2
797
// return 0
798
// else
799
// Dst = Src1 + Src2 - Dst.capacity
800
// return 1
801
// The return value is a carry output of the addition.
802
//
803
// Dst may be the same object as Src1, Src2, or both.
804
//
805
806
UINT32
807
SYMCRYPT_CALL
808
SymCryptIntAddMixedSize(
809
_In_ PCSYMCRYPT_INT piSrc1,
810
_In_ PCSYMCRYPT_INT piSrc2,
811
_Out_ PSYMCRYPT_INT piDst );
812
//
813
// Dst = Src1 + Src2.
814
// Requirement: Dst.nDigits >= max( Src1.nDigits, Src2.nDigits )
815
// In more detail:
816
// if Src1 + Src2 < Dst.capacity:
817
// Dst = Src1 + Src2
818
// return 0
819
// else
820
// Dst = Src1 + Src2 - Dst.capacity
821
// return 1
822
// The return value is a carry output of the addition.
823
//
824
// Dst may be the same object as Src1, Src2, or both.
825
//
826
827
//
828
// Subtraction
829
// Subtraction functions are the equivalent of addition functions.
830
// The return value is 1 if an underflow occurred (borrow), and 0 if no underflow/borrow occurred.
831
// On underflow, the value of the result is the result of the subtraction plus Dst.capacity.
832
//
833
// Rationale: For an underflow we could also return (UINT32)-1 or return -1 on a INT32.
834
// -1 in an unsigned type is actually 2^32 -1 which makes no sense.
835
// Returning a signed type is somewhat neater, but all other values are unsigned, and mixing
836
// signed and unsigned types is always error-prone. Furthermore, converting from a signed integer
837
// to a mask is also error-prone (at least within the behaviour guaranteed by the C standard.)
838
// Returning an unsigned 1 is therefore preferred.
839
//
840
841
UINT32
842
SYMCRYPT_CALL
843
SymCryptIntSubUint32(
844
_In_ PCSYMCRYPT_INT piSrc1,
845
UINT32 Src2,
846
_Out_ PSYMCRYPT_INT piDst );
847
848
UINT32
849
SYMCRYPT_CALL
850
SymCryptIntSubSameSize(
851
_In_ PCSYMCRYPT_INT piSrc1,
852
_In_ PCSYMCRYPT_INT piSrc2,
853
_Out_ PSYMCRYPT_INT piDst );
854
855
UINT32
856
SYMCRYPT_CALL
857
SymCryptIntSubMixedSize(
858
_In_ PCSYMCRYPT_INT piSrc1,
859
_In_ PCSYMCRYPT_INT piSrc2,
860
_Out_ PSYMCRYPT_INT piDst );
861
862
VOID
863
SYMCRYPT_CALL
864
SymCryptIntNeg(
865
_In_ PCSYMCRYPT_INT piSrc,
866
_Out_ PSYMCRYPT_INT piDst );
867
868
//
869
// Dst = (- Src) mod Dst.Capacity;
870
// Requirement:
871
// - Dst.nDigits == Src.nDigits;
872
// This is a negate modulo the capacity.
873
// Useful when you want the absolute value of a difference.
874
// Compute the difference, and if the subtraction yields a carry, negate the result.
875
//
876
877
//===================================================================
878
// Shifts
879
// Note that the shift amount is always published.
880
// If the need arises, we can define variants that are side-channel safe
881
// w.r.t. the shift size, but that incurs a significant performance cost.
882
//
883
884
VOID
885
SYMCRYPT_CALL
886
SymCryptIntMulPow2(
887
_In_ PCSYMCRYPT_INT piSrc,
888
SIZE_T exp,
889
_Out_ PSYMCRYPT_INT piDst );
890
//
891
// Dst = (Src * 2^Exp ) mod R^n where n = Dst.nDigits.
892
// Requirement: Dst.nDigits == Src.nDigits, Dst == Src is allowed
893
// Exp is published.
894
//
895
// A variant that keeps Exp private is currently not available, but can be added to the API if needed.
896
// (A side-channel safe variant might require scratch space.)
897
//
898
// Dst may be the same object as Src1.
899
//
900
901
VOID
902
SYMCRYPT_CALL
903
SymCryptIntDivPow2(
904
_In_ PCSYMCRYPT_INT piSrc,
905
SIZE_T exp,
906
_Out_ PSYMCRYPT_INT piDst );
907
//
908
// Dst = (Src div 2^Exp )
909
// Requirement: Dst.nDigits == Src.nDigits, Dst == Src is allowed
910
// Exp is published
911
//
912
// A variant that keeps Exp private is currently not available, but can be added to the API if needed.
913
// (A side-channel safe variant might require scratch space.)
914
//
915
// Dst may be the same object as Src1.
916
//
917
918
VOID
919
SYMCRYPT_CALL
920
SymCryptIntShr1(
921
UINT32 highestBit,
922
_In_ PCSYMCRYPT_INT piSrc,
923
_Out_ PSYMCRYPT_INT piDst );
924
//
925
// Dst = (Src + highestBit * Src.Capacity) div 2
926
//
927
// Requirements:
928
// Src.nDigits == Dst.nDigits
929
// highestBit <= 1
930
//
931
// This is the Int equivalent of the 'shift right 1' instruction.
932
// Shifting by one can be implemented faster than variable sized shifts.
933
//
934
935
VOID
936
SYMCRYPT_CALL
937
SymCryptIntModPow2(
938
_In_ PCSYMCRYPT_INT piSrc,
939
SIZE_T exp,
940
_Out_ PSYMCRYPT_INT piDst );
941
//
942
// Dst = Src mod 2^Exp
943
// Requirement: Dst.nDigits == Src.nDigits, Dst == Src is allowed
944
// Exp is published
945
//
946
// Dst may be the same object as Src1.
947
//
948
949
UINT32
950
SYMCRYPT_CALL
951
SymCryptIntGetBit(
952
_In_ PCSYMCRYPT_INT piSrc,
953
UINT32 iBit );
954
//
955
// Returns the i-th bit (starting from 0 for the LSB) of piSrc.
956
// Therefore the only possible return values are 0 and 1.
957
//
958
// Requirements:
959
// - iBit < SymCryptIntBitsizeOfObject( piSrc )
960
//
961
962
UINT32
963
SYMCRYPT_CALL
964
SymCryptIntGetBits(
965
_In_ PCSYMCRYPT_INT piSrc,
966
UINT32 iBit,
967
UINT32 nBits );
968
//
969
// Returns the bits from position iBit up to (iBit + nBits - 1)
970
// (starting from 0 for the LSB). Total of nBits. The 0-th bit of
971
// the return value corresponds to the iBit-th bit of the source.
972
//
973
// Requirements:
974
// - 1 <= nBits <= 32
975
// - iBit + nBits <= SymCryptIntBitsizeOfObject( piSrc )
976
//
977
// Remarks:
978
// - The values iBit and nBits are not protected by side-channel attacks,
979
// therefore they should be treated as published.
980
// - The bits of the return value after the (nBits)-th bit are zero.
981
//
982
983
VOID
984
SYMCRYPT_CALL
985
SymCryptIntSetBits(
986
_In_ PSYMCRYPT_INT piDst,
987
UINT32 value,
988
UINT32 iBit,
989
UINT32 nBits );
990
//
991
// Sets the bits from position iBit up to (iBit + nBits - 1)
992
// (starting from 0 for the LSB). Total of nBits. The 0-th bit of
993
// the input value corresponds to the iBit-th bit of the destination.
994
//
995
// Requirements:
996
// - 1 <= nBits <= 32
997
// - iBit + nBits <= SymCryptIntBitsizeOfObject( piSrc )
998
//
999
// Remarks:
1000
// - The values iBit and nBits are not protected by side-channel attacks,
1001
// therefore they should be treated as published.
1002
// - The bits of the value after the (nBits)-th bit are ignored.
1003
//
1004
1005
//===========================================================
1006
// Mul & div
1007
//
1008
1009
UINT32
1010
SYMCRYPT_CALL
1011
SymCryptIntMulUint32(
1012
_In_ PCSYMCRYPT_INT piSrc1,
1013
UINT32 Src2,
1014
_Out_ PSYMCRYPT_INT piDst );
1015
//
1016
// Dst = Src1 * Src2 mod Dst.capacity; return value = Src1 * Src2 div Dst.capacity
1017
// Requirement: piDst.nDigits == piSrc1.nDigits, Dst == Src is allowed
1018
//
1019
1020
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_MUL( _nResultDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_MUL( _nResultDigits )
1021
1022
VOID
1023
SYMCRYPT_CALL
1024
SymCryptIntMulSameSize(
1025
_In_ PCSYMCRYPT_INT piSrc1,
1026
_In_ PCSYMCRYPT_INT piSrc2,
1027
_Out_ PSYMCRYPT_INT piDst,
1028
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1029
SIZE_T cbScratch );
1030
//
1031
// Dst = Src1 * Src2.
1032
// Requirement:
1033
// - Src1.nDigits == Src2.nDigits; Dst.nDigits == Src1.nDigits + Src2.nDigits
1034
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_INT_MUL( Dst.nDigits )
1035
//
1036
// Note that Dst cannot be the same object as Src1 or Src2 because of the size restrictions.
1037
//
1038
1039
VOID
1040
SYMCRYPT_CALL
1041
SymCryptIntSquare(
1042
_In_ PCSYMCRYPT_INT piSrc,
1043
_Out_ PSYMCRYPT_INT piDst,
1044
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1045
SIZE_T cbScratch );
1046
//
1047
// Dst = Src^2
1048
// Requirement:
1049
// - Dst.nDigits == 2 * Src.nDigits
1050
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_INT_MUL( Dst.nDigits )
1051
//
1052
// Note that Dst cannot be the same object as Src1 or Src2 because of the size restrictions.
1053
//
1054
1055
VOID
1056
SYMCRYPT_CALL
1057
SymCryptIntMulMixedSize(
1058
_In_ PCSYMCRYPT_INT piSrc1,
1059
_In_ PCSYMCRYPT_INT piSrc2,
1060
_Out_ PSYMCRYPT_INT piDst,
1061
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1062
SIZE_T cbScratch );
1063
//
1064
// Dst = Src1 * Src2.
1065
// Requirement:
1066
// - Dst.nDigits >= Src1.nDigits + Src2.nDigits
1067
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_INT_MUL( Dst.nDigits )
1068
//
1069
// Note that Dst cannot be the same object as Src1 or Src2 because of the size restrictions.
1070
//
1071
1072
1073
//
1074
// Division
1075
// For all division and modulo operations, there are pre-computations that have to be done
1076
// on the divisor. The pre-computed divisor information is stored in a DIVISOR object.
1077
// Note that the bitsize of the value of the divisor is published.
1078
// Therefore, a generic division is not side-channel safe.
1079
// Rationale: Hiding the bitsize of the value of the divisor is quite expensive,
1080
// and we have no cryptographic algorithms that require it.
1081
//
1082
1083
1084
PSYMCRYPT_INT
1085
SYMCRYPT_CALL
1086
SymCryptIntFromDivisor( _In_ PSYMCRYPT_DIVISOR pdSrc );
1087
//
1088
// Returns the INT object inside the DIVISOR object.
1089
// Digit size of the INT object is equal to the digit size of the DIVISOR object.
1090
// This object has two uses:
1091
// - On an uninitialized DIVISOR object it is a suitable place to put a value before calling
1092
// SymCryptIntToDivisor.
1093
// - On an initialized DIVISOR object the function returns a pointer to the INT that contains
1094
// the divisor value. Modifying the INT value from an initialized DIVISOR value corrupts
1095
// the divisor value.
1096
//
1097
// This is typically a very fast function, with a run-time cost that is zero or only one instruction.
1098
//
1099
1100
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits )
1101
1102
VOID
1103
SYMCRYPT_CALL
1104
SymCryptIntToDivisor(
1105
_In_ PCSYMCRYPT_INT piSrc,
1106
_Out_ PSYMCRYPT_DIVISOR pdDst,
1107
UINT32 totalOperations,
1108
UINT32 flags,
1109
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1110
SIZE_T cbScratch );
1111
//
1112
// Create a DIVISOR object from an INT.
1113
// Requirement:
1114
// - Dst.nDigits == Src.nDigits
1115
// - Src != 0
1116
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( Src.nDigits )
1117
// SymCryptIntBitsizeOfValue( Src ) is published.
1118
// Src may be equal to SymCryptIntFromDivisor( Dst ).
1119
// totalOperations is an estimate of how many divide/modulo operations will be performed with this divisor.
1120
// An implementation may use this to decide how much pre-computations to do.
1121
// flags: any combination of the following flag values:
1122
// - SYMCRYPT_FLAG_DATA_PUBLIC
1123
// Signals that the Src value is public.
1124
// Implementations can use this to use more efficient divisor algorithms depending on the actual value of Src.
1125
// For example, if Src is very close to a power of 2, division can be implemented more efficiently.
1126
//
1127
// Once a divisor object has been created, it is immutable.
1128
// Multiple threads can use the same divisor object for different division operations in parallel.
1129
//
1130
1131
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_DIVMOD( _nSrcDigits, _nDivisorDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_DIVMOD( _nSrcDigits, _nDivisorDigits )
1132
1133
VOID
1134
SYMCRYPT_CALL
1135
SymCryptIntDivMod(
1136
_In_ PCSYMCRYPT_INT piSrc,
1137
_In_ PCSYMCRYPT_DIVISOR pdDivisor,
1138
_Out_opt_ PSYMCRYPT_INT piQuotient,
1139
_Out_opt_ PSYMCRYPT_INT piRemainder,
1140
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1141
SIZE_T cbScratch );
1142
//
1143
// Quotient = Src div Divisor
1144
// Remainder = Src mod Divisor
1145
// Quotient & Remainder may be NULL in which case that result is not returned.
1146
// Requirements:
1147
// - Quotient.nDigits >= Src.nDigits
1148
// - Remainder.nDigits >= Divisor.nDigits
1149
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_INT_DIVMOD( Src.nDigits, Divisor.nDigits )
1150
// Quotient and Remainder must be different objects.
1151
// Src may be the same object as either Quotient or Remainder.
1152
//
1153
1154
#define SYMCRYPT_SCRATCH_BYTES_FOR_EXTENDED_GCD( _nDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_EXTENDED_GCD( _nDigits )
1155
1156
VOID
1157
SYMCRYPT_CALL
1158
SymCryptIntExtendedGcd(
1159
_In_ PCSYMCRYPT_INT piSrc1,
1160
_In_ PCSYMCRYPT_INT piSrc2,
1161
UINT32 flags,
1162
_Out_opt_ PSYMCRYPT_INT piGcd,
1163
_Out_opt_ PSYMCRYPT_INT piLcm,
1164
_Out_opt_ PSYMCRYPT_INT piInvSrc1ModSrc2,
1165
_Out_opt_ PSYMCRYPT_INT piInvSrc2ModSrc1,
1166
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1167
SIZE_T cbScratch );
1168
//
1169
// Compute up to four results from Src1 and Src2.
1170
// GCD is the greatest common divisor of Src1 and Src2.
1171
// LCM is the Least Common Multiple of Src1 and Src2.
1172
// InvSrc1ModSrc2 is the smallest value such that (InvSrc1ModSrc2 * Src1) mod Src2= GCD( Src1, Src2 )
1173
// UNLESS Src1 is a multiple of Src2, i.e. when Src1 = 0 mod Src2. In this case the result is
1174
// undefined.
1175
// InvSrc2ModSrc1 is the smallest value such that (InvSrc2ModSrc1 * Src2) mod Src1= GCD( Src1, Src2 )
1176
// UNLESS Src2 is a multiple of Src1, i.e. when Src2 = 0 mod Src1. In this case the result is
1177
// undefined.
1178
//
1179
// The last two modular inverse values are not true modular inverses unless GCD( Src1, Src2 ) = 1.
1180
//
1181
// Any of the output pointers can be NULL and then that result is not returned.
1182
// Requirements:
1183
// - Src1 > 0
1184
// - Src2 > 0 and Src2 odd
1185
// - Gcd.nDigits >= min( Src1.nDigits, Src2.nDigits )
1186
// - Lcm.nDigits >= Src1.nDigits + Src2.nDigits
1187
// - InvSrc1ModSrc2.nDigits >= max(Src1.nDigits, Src2.nDigits) // Future work: Make these bounds Src2 and Src1 respectively.
1188
// - InvSrc2ModSrc1.nDigits >= max(Src1.nDigits, Src2.nDigits)
1189
// - if piInvSrc2ModSrc1 is not NULL, max( Src1.nDigits, Src2.nDigits ) * 2 <= SymCryptDigitsFromBits(SYMCRYPT_INT_MAX_BITS)
1190
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_EXTENDED_GCD( max( Src1.nDigits, Src2.nDigits ) )
1191
//
1192
// If only one inverse value is needed, it is most efficient to use only InvSrc1ModSrc2.
1193
//
1194
// The restriction that Src2 must be odd can be removed in a future version.
1195
// The SYMCRYPT_FLAG_DATA_PUBLIC flag signals that the inputs are public information and do not have
1196
// to be side-channel protected.
1197
// The SYMCRYPT_FLAG_GCD_INPUTS_NOT_BOTH_EVEN signals that at least one input is odd. This speeds up the
1198
// side-channel safe implementation; this flag is not needed if the inputs are signaled as public as the code can then
1199
// afford to check that condition and change use a optimized algorithm.
1200
// The SYMCRYPT_FLAG_GCD_PUBLIC signals that the GCD value is public. This can make some computations
1201
// (of the inverses) more efficient when GCD = 1.
1202
//
1203
1204
#define SYMCRYPT_FLAG_GCD_INPUTS_NOT_BOTH_EVEN (0x02)
1205
#define SYMCRYPT_FLAG_GCD_PUBLIC (0x04)
1206
1207
1208
UINT64
1209
SYMCRYPT_CALL
1210
SymCryptUint64Gcd( UINT64 a, UINT64 b, UINT32 flags );
1211
//
1212
// Return GCD of two 64-bit integers.
1213
// a, b : inputs to the GCD
1214
// flags:
1215
// - SYMCRYPT_FLAG_DATA_PUBLIC signals that a and b are public values (w.r.t. side-channel safety)
1216
// This may improve performance.
1217
// - SYMCRYPT_FLAG_GCD_INPUTS_NOT_BOTH_EVEN: signals that at least one of (a,b) is odd. This
1218
// simplifies & speeds up the GCD computation.
1219
//
1220
// Note:
1221
// The current implementation requires that the INPUTS_NOT_BOTH_EVEN flag is set (and at least one input be odd).
1222
// Also note that GCD(x, 0) == GCD(0, x) == x
1223
//
1224
1225
1226
#define SYMCRYPT_SCRATCH_BYTES_FOR_CRT_GENERATION( _nDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_CRT_GENERATION( _nDigits )
1227
1228
SYMCRYPT_ERROR
1229
SYMCRYPT_CALL
1230
SymCryptCrtGenerateInverses(
1231
UINT32 nCoprimes,
1232
_In_reads_( nCoprimes ) PCSYMCRYPT_MODULUS * ppmCoprimes,
1233
UINT32 flags,
1234
_Out_writes_( nCoprimes ) PSYMCRYPT_MODELEMENT * ppeCrtInverses,
1235
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1236
SIZE_T cbScratch );
1237
//
1238
// Compute the Chinese Remainder Theorem (CRT) constants for a set of nCoprimes
1239
// pairwise coprime moduli. Pointers to the input numbers are stored in the array of
1240
// pointers ppmCoprimes, while the outputs are stored to the locations pointed by
1241
// ppeCrtInverses.
1242
//
1243
// For input numbers Src1, Src2, ..., SrcK where K = nCoprimes, let N = Src1*Src2*...*SrcK.
1244
// Then this function outputs the constants:
1245
// (( Src1 / N ) mod Src1), (( Src2 / N ) mod Src2), ..., (( SrcK / N ) mod SrcK)
1246
//
1247
// The most common case is for the RSA algorithm where the inputs are 2 prime numbers P and Q
1248
// and only Q^{-1} mod P is needed (i.e. only the first term of the output array).
1249
//
1250
// Any of the output pointers in the ppeCrtInverses can be NULL and then that result
1251
// is not returned (resulting in a faster total running time).
1252
//
1253
// The number of inputs nCoprimes and which outputs are returned is public.
1254
//
1255
// Requirements:
1256
// - nCoprimes >= 2
1257
// - Both ppmCoprimes and ppeCrtInverses must be arrays of pointers of exactly nCoprimes pointers.
1258
// - ppmCoprimes[i] != NULL for all i in [0, nCoprimes-1].
1259
// - The input moduli must be pairwise coprime.
1260
// - The number of digits of all input moduli must match the number of digits of the corresponding
1261
// output modelements.
1262
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_CRT_GENERATION( nDigits ) where nDigits is the maximum number
1263
// of digits of the inputs and outputs.
1264
//
1265
1266
#define SYMCRYPT_SCRATCH_BYTES_FOR_CRT_SOLUTION( _nDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_CRT_SOLUTION( _nDigits )
1267
1268
SYMCRYPT_ERROR
1269
SYMCRYPT_CALL
1270
SymCryptCrtSolve(
1271
UINT32 nCoprimes,
1272
_In_reads_( nCoprimes ) PCSYMCRYPT_MODULUS * ppmCoprimes,
1273
_In_reads_( nCoprimes ) PCSYMCRYPT_MODELEMENT * ppeCrtInverses,
1274
_In_reads_( nCoprimes ) PCSYMCRYPT_MODELEMENT * ppeCrtRemainders,
1275
UINT32 flags,
1276
_Out_ PSYMCRYPT_INT piSolution,
1277
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1278
SIZE_T cbScratch );
1279
//
1280
// Solve for x the system of nCoprimes congruences of the form
1281
// x = ppeCrtRemainders[0] (mod ppmCoprimes[0])
1282
// x = ppeCrtRemainders[1] (mod ppmCoprimes[1])
1283
// ...
1284
// x = ppeCrtRemainders[nCoprimes-1] (mod ppmCoprimes[nCoprimes-1])
1285
//
1286
// The input array ppeCrtInverses must have been pre-computed by a call to SymCryptCrtGenerateInverses.
1287
//
1288
// The number of inputs nCoprimes is public.
1289
//
1290
// Requirements:
1291
// - nCoprimes == 2
1292
// - ppmCoprimes, ppeCrtInverses, and ppeCrtRemainders must be arrays of pointers of exactly nCoprimes elements. All
1293
// of them non-NULL.
1294
// - piSolution must be large enough to hold the result modulo the product of all the coprimes.
1295
// - max( ppmCoprimes[0].nDigits, ppmCoprimes[1].nDigits ) * 2 <= SymCryptDigitsFromBits(SYMCRYPT_INT_MAX_BITS)
1296
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_CRT_SOLUTION( nDigits ) where nDigits is the maximum number
1297
// of digits of the input moduli.
1298
//
1299
1300
1301
typedef const struct _SYMCRYPT_TRIALDIVISION_CONTEXT *PCSYMCRYPT_TRIALDIVISION_CONTEXT;
1302
1303
PCSYMCRYPT_TRIALDIVISION_CONTEXT
1304
SYMCRYPT_CALL
1305
SymCryptCreateTrialDivisionContext( UINT32 nDigits );
1306
//
1307
// Create a trial division context that can be used for integers up to and including nDigits digits.
1308
// The Trial division context can be used in multiple threads in parallel.
1309
// The context should be freed with SymCryptFreeTrialDivisionContext after use.
1310
// A context can be fairly large (100 kB) so freeing it is important.
1311
// Returns NULL if out of memory or an invalid digit count is provided.
1312
//
1313
1314
VOID
1315
SYMCRYPT_CALL
1316
SymCryptFreeTrialDivisionContext( PCSYMCRYPT_TRIALDIVISION_CONTEXT pContext );
1317
//
1318
// Free the trial division context after use.
1319
//
1320
1321
UINT32
1322
SYMCRYPT_CALL
1323
SymCryptIntFindSmallDivisor(
1324
_In_ PCSYMCRYPT_TRIALDIVISION_CONTEXT pContext,
1325
_In_ PCSYMCRYPT_INT piSrc,
1326
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1327
SIZE_T cbScratch );
1328
//
1329
// Returns a divisor of piSrc, or zero.
1330
// Requirements:
1331
// Requirement:
1332
// - pContext is a valid trial division context, and Context.nDigits >= Src.nDigits
1333
// - Src >= 2
1334
// Note:
1335
// - Src is published if this function returns a divisor.
1336
//
1337
// There is no guarantee that this function finds small divisors;
1338
// it is valid for the implementation to always return 0.
1339
// Any nonzero return value is always >= 2 and an actual divisor of Src.
1340
// Note: this function might not find 2 as a small divisor.
1341
//
1342
1343
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_IS_PRIME( _nDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_IS_PRIME( _nDigits )
1344
1345
UINT32
1346
SYMCRYPT_CALL
1347
SymCryptIntMillerRabinPrimalityTest(
1348
_In_ PCSYMCRYPT_INT piSrc,
1349
UINT32 nBitsSrc,
1350
UINT32 nIterations,
1351
UINT32 flags,
1352
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1353
SIZE_T cbScratch );
1354
//
1355
// Applies the Miller-Rabin prime testing algorithm using nIterations on the integer
1356
// piSrc.
1357
//
1358
// The maximum bitsize of the value of piSrc is equal to nBitsSrc and it is public.
1359
// The number of iterations nIterations is also public.
1360
//
1361
// If the return value is 0, then Src is guaranteed to be a composite value.
1362
// In this case, the value of Src is treated as public.
1363
//
1364
// If the return value is 0xffffffff, then Src might be prime.
1365
// In this case, the value of Src is treated as private except when the
1366
// SYMCRYPT_FLAG_DATA_PUBLIC flag is specified.
1367
//
1368
// If the flag SYMCRYPT_FLAG_DATA_PUBLIC is specified the
1369
// algorithm leaks the number of trailing zeros of Src-1. The reason for
1370
// not having a fully side-channel safe implementation for arbitrary
1371
// numbers is that such a function would be prohibitively slow.
1372
//
1373
// Requirements:
1374
// - SymCryptIntBitsizeOfValue( piSrc ) <= nBitsSrc <= SymCryptIntBitsizeOfObject( piSrc )
1375
// - Src is odd and greater than 3.
1376
// - If flags == 0 then Src must be 3 modulo 4. (See the comment above for
1377
// the SYMCRYPT_FLAG_DATA_PUBLIC flag)
1378
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_INT_IS_PRIME( Src.nDigits )
1379
//
1380
1381
//
1382
1383
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_PRIME_GEN( _nDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_PRIME_GEN( _nDigits )
1384
1385
SYMCRYPT_ERROR
1386
SYMCRYPT_CALL
1387
SymCryptIntGenerateRandomPrime(
1388
_In_ PCSYMCRYPT_INT piLow,
1389
_In_ PCSYMCRYPT_INT piHigh,
1390
_In_reads_opt_( nPubExp ) PCUINT64 pu64PubExp,
1391
UINT32 nPubExp,
1392
UINT32 nTries,
1393
UINT32 flags,
1394
_Inout_ PSYMCRYPT_INT piDst,
1395
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1396
SIZE_T cbScratch );
1397
//
1398
// This function generates a random prime Dst such that
1399
// Dst == 3 mod 4 and
1400
// Low <= Dst < High
1401
// for e in PubExp[]: GCD( Dst - 1, e ) == 1
1402
//
1403
// (pu64PubExp, nPubExp) can be (NULL, 0) if no pubexp restriction is needed.
1404
// The nTries parameter specifies the maximum number of candidate numbers
1405
// until a prime number is found satisfying the above restrictions.
1406
// If the function cannot find one after nTries, it returns SYMCRYPT_INVALID_ARGUMENT
1407
// (For example, if the caller passes in a Low bound bigger than the High bound,
1408
// or if there are no primes between Low and High).
1409
//
1410
// The values of the pubexps, piLow and piHigh are public.
1411
//
1412
// flags: None
1413
//
1414
// Requirements:
1415
// - SymCryptIntBitsizeOfValue( piHigh ) <= SymCryptIntBitsizeOfObject(piDst)
1416
// - piLow > 3
1417
// - Each public exponent must be greater than 0
1418
// - 0 <= nPubExp <= SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS
1419
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_INT_PRIME_GEN( Dst.nDigits )
1420
//
1421
1422
//=====================================================
1423
// Modular arithmetic
1424
//
1425
// To perform modular arithmetic the modulus has to be prepared into a Modulus object.
1426
// Arithmetic in the ring modulo the modulus can then be done using ModElement objects.
1427
//
1428
1429
PSYMCRYPT_DIVISOR
1430
SYMCRYPT_CALL
1431
SymCryptDivisorFromModulus( _In_ PSYMCRYPT_MODULUS pmSrc );
1432
//
1433
// Returns the DIVISOR object inside the MODULUS object.
1434
//
1435
// Digit size of the DIVISOR object is equal to the digit size of the MODULUS object.
1436
// This object has one use:
1437
// - On an initialized MODULUS object the function returns a pointer to the DIVISOR that contains
1438
// the modulus value. Modifying the DIVISOR value from an initialized MODULUS value corrupts
1439
// the modulus.
1440
//
1441
// This is typically a very fast function, with a run-time cost that is zero or one instruction.
1442
//
1443
1444
PSYMCRYPT_INT
1445
SYMCRYPT_CALL
1446
SymCryptIntFromModulus( _In_ PSYMCRYPT_MODULUS pmSrc );
1447
//
1448
// Returns the INT object inside the MODULUS object.
1449
//
1450
// Digit size of the INT object is equal to the digit size of the MODULUS object.
1451
// This object has two uses:
1452
// - On an uninitialized MODULUS object it is a suitable place to put a value before calling
1453
// SymCryptIntToModulus.
1454
// - On an initialized MODULUS object the function returns a pointer to the INT that contains
1455
// the modulus value. Modifying the INT value from an initialized MODULUS value corrupts
1456
// the modulus.
1457
//
1458
// This is typically a very fast function, with a run-time cost that is zero or one instruction.
1459
//
1460
1461
#define SYMCRYPT_SCRATCH_BYTES_FOR_INT_TO_MODULUS( _nDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_TO_MODULUS( _nDigits )
1462
1463
VOID
1464
SYMCRYPT_CALL
1465
SymCryptIntToModulus(
1466
_In_ PCSYMCRYPT_INT piSrc,
1467
_Out_ PSYMCRYPT_MODULUS pmDst,
1468
UINT32 averageOperations,
1469
UINT32 flags,
1470
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1471
SIZE_T cbScratch );
1472
//
1473
// Create a modulus from an INT.
1474
// Requirements:
1475
// - Src != 0
1476
// - Dst.nDigits == Src.nDigits
1477
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_INT_TO_MODULUS( Src.nDigits )
1478
// SymCryptIntBitsizeOfValue( Src ) is published.
1479
// averageOperations is the average number of multiplications that are performed on a ModElement created with this modulus between the time that the value is
1480
// created as a ModElement and the time it is exported out of modElement form.
1481
// There are multiple ways of doing modular computations; some of them are faster but have an overhead for converting into and out of modular form.
1482
// For example, for RSA verification the # operations is small and conversion overhead should be avoided.
1483
// For RSA signatures, the # operations is large and the fastest per-operation form should be used.
1484
// This parameter allows the library to select the right kind of modular arithmetic for this modulus.
1485
// The following flags are supported:
1486
// SYMCRYPT_FLAG_DATA_PUBLIC
1487
// Signals the code that the Src value is public. This may improve performance because it allows further optimizations that
1488
// depend on the value. (For example, if Src is close to a power of 2, the modulo reduction can be made significantly faster.)
1489
// SYMCRYPT_FLAG_MODULUS_PARITY_PUBLIC
1490
// Signals that the parity of Src (whether it is even or odd) may be treated as a public value.
1491
// There are some algorithms that can speed up operations on odd moduli, but their use publishes the fact that the modulus is odd.
1492
// SYMCRYPT_FLAG_MODULUS_ADDITIVE_ONLY
1493
// The modulus will only be used for addition and subtraction, not for multiplication or division.
1494
// This can significantly reduce the cost of this function as there is no need to pre-compute the divisor information.
1495
// SYMCRYPT_FLAG_MODULUS_PRIME
1496
// Signals that the modulus is a prime. Some algorithms can be more efficient for prime moduli. Note that setting this flag
1497
// for a non-prime modulus can result in incorrect answers.
1498
// The flags and averageOperations parameters are published.
1499
//
1500
1501
#define SYMCRYPT_FLAG_MODULUS_PARITY_PUBLIC (0x02)
1502
#define SYMCRYPT_FLAG_MODULUS_ADDITIVE_ONLY (0x04)
1503
#define SYMCRYPT_FLAG_MODULUS_PRIME (0x08)
1504
1505
#define SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nDigits )
1506
1507
1508
VOID
1509
SYMCRYPT_CALL
1510
SymCryptIntToModElement(
1511
_In_ PCSYMCRYPT_INT piSrc,
1512
_In_ PCSYMCRYPT_MODULUS pmMod,
1513
_Out_ PSYMCRYPT_MODELEMENT peDst,
1514
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1515
SIZE_T cbScratch );
1516
//
1517
// Dst = Src mod Mod
1518
// Requirements:
1519
// - Dst.nDigits == Mod.nDigits
1520
// - piSrc.nDigits <= 2 * Mod.nDigits
1521
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1522
//
1523
// Note: the input is limited in size to be no more than twice the modulus size (in digits).
1524
// This should be a rare case, and it simplifies the scratch space handling significantly.
1525
//
1526
1527
VOID
1528
SYMCRYPT_CALL
1529
SymCryptModElementToInt(
1530
_In_ PCSYMCRYPT_MODULUS pmMod,
1531
_In_ PCSYMCRYPT_MODELEMENT peSrc,
1532
_Out_ PSYMCRYPT_INT piDst,
1533
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1534
SIZE_T cbScratch );
1535
//
1536
// Dst = Src
1537
//
1538
// Requirement:
1539
// - Dst.nDigits >= Mod.nDigits
1540
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1541
//
1542
// Convert a ModElement to an Int.
1543
// The internal format in which a ModElement is stored might be different
1544
// from the format of an Int; this function converts the value to the INT format.
1545
//
1546
1547
1548
SYMCRYPT_ERROR
1549
SYMCRYPT_CALL
1550
SymCryptModElementSetValue(
1551
_In_reads_bytes_( cbSrc ) PCBYTE pbSrc,
1552
SIZE_T cbSrc,
1553
SYMCRYPT_NUMBER_FORMAT format,
1554
PCSYMCRYPT_MODULUS pmMod,
1555
_Out_ PSYMCRYPT_MODELEMENT peDst,
1556
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1557
SIZE_T cbScratch );
1558
//
1559
// Dst = decode( pbSrc, cbSrc, format ) mod Mod
1560
// Requirement:
1561
// - SymCryptDigitsFromBits( 8 * cbSrc ) <= Mod.nDigits
1562
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1563
//
1564
// This is a separate function as it is frequently used, and does not require the allocation of an INT object.
1565
//
1566
1567
VOID
1568
SYMCRYPT_CALL
1569
SymCryptModElementSetValueUint32(
1570
UINT32 value,
1571
_In_ PCSYMCRYPT_MODULUS pmMod,
1572
_Out_ PSYMCRYPT_MODELEMENT peDst,
1573
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1574
SIZE_T cbScratch );
1575
//
1576
// Dst = value mod Mod
1577
// value is published.
1578
// Requirement:
1579
// - value < Mod
1580
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1581
// Note: this function does NOT hide the value.
1582
// Rationale: typically the value parameter is known, either 0 or 1.
1583
//
1584
1585
VOID
1586
SYMCRYPT_CALL
1587
SymCryptModElementSetValueNegUint32(
1588
UINT32 value,
1589
_In_ PCSYMCRYPT_MODULUS pmMod,
1590
_Out_ PSYMCRYPT_MODELEMENT peDst,
1591
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1592
SIZE_T cbScratch );
1593
//
1594
// Dst = -value mod Mod
1595
// value is published.
1596
// Requirement:
1597
// - 0 < value < Mod
1598
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1599
// Note: this function does NOT hide the value.
1600
// Rationale: typically the value parameter is known, either 0 or 1.
1601
//
1602
1603
1604
SYMCRYPT_ERROR
1605
SYMCRYPT_CALL
1606
SymCryptModElementGetValue(
1607
PCSYMCRYPT_MODULUS pmMod,
1608
_In_ PCSYMCRYPT_MODELEMENT peSrc,
1609
_Out_writes_bytes_( cbDst ) PBYTE pbDst,
1610
SIZE_T cbDst,
1611
SYMCRYPT_NUMBER_FORMAT format,
1612
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1613
SIZE_T cbScratch );
1614
//
1615
// (pbDst, cbDst) = encode( format, cbDst, Src )
1616
// Requirement:
1617
// - SymCryptDigitsFromBits( 8 * cbDst ) <= Mod.nDigits
1618
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1619
//
1620
// Retrieve the value of a ModElement as an array of bytes
1621
//
1622
1623
UINT32
1624
SYMCRYPT_CALL
1625
SymCryptModElementIsEqual(
1626
_In_ PCSYMCRYPT_MODULUS pmMod,
1627
_In_ PCSYMCRYPT_MODELEMENT peSrc1,
1628
_In_ PCSYMCRYPT_MODELEMENT peSrc2 );
1629
//
1630
// Returns a mask value which is 0xffffffff if Src1 = Src2 and 0 otherwise.
1631
//
1632
// Both SYMCRYPT_MODELEMENTs should have been created using the modulus pmMod. Otherwise
1633
// the result is undefined.
1634
//
1635
1636
UINT32
1637
SYMCRYPT_CALL
1638
SymCryptModElementIsZero(
1639
_In_ PCSYMCRYPT_MODULUS pmMod,
1640
_In_ PCSYMCRYPT_MODELEMENT peSrc );
1641
//
1642
// Returns a mask value which is 0xffffffff if Src = 0 and 0 otherwise.
1643
//
1644
// Useful for quickly checking if a ModElement is 0.
1645
//
1646
1647
1648
//===============================
1649
// Modular arithmetic.
1650
//
1651
1652
VOID
1653
SYMCRYPT_CALL
1654
SymCryptModSetRandom(
1655
_In_ PCSYMCRYPT_MODULUS pmMod,
1656
_Out_ PSYMCRYPT_MODELEMENT peDst,
1657
UINT32 flags,
1658
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1659
SIZE_T cbScratch );
1660
//
1661
// Dst = random value modulus Mod.
1662
// Requirement:
1663
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1664
//
1665
// Random value is chosen uniformly from the set of allowed values.
1666
// By default this function does not return the values 0, 1, or -1 (see below NOTE for small moduli exception)
1667
// Flags parameter can signal that these special values are allowed.
1668
// flags parameter is published.
1669
//
1670
// Rationale: these values cause problems in many situations, and for all commonly used cryptographic modulo sizes
1671
// the absence of these values is statistically undetectable even if they are allowed.
1672
// For completeness of the API, the flags parameter can be used to allow these three values.
1673
// flags is a bitmask containing a combination of the following bit values:
1674
// SYMCRYPT_FLAG_MODRANDOM_ALLOW_ZERO
1675
// SYMCRYPT_FLAG_MODRANDOM_ALLOW_ONE
1676
// SYMCRYPT_FLAG_MODRANDOM_ALLOW_MINUSONE
1677
// Specifying ALLOW_ZERO implies ALLOW_ONE, there is no way to allow 0 and disallow 1.
1678
//
1679
// NOTE:
1680
// For very small moduli (1, 2, and 3), not allowing 0, 1, or -1 by default does not make sense because this would
1681
// exclude all possible values! Instead the default behavior is to allow -1 for these moduli.
1682
// Modulo 1 => return 0 by default
1683
// Modulo 2 => return 1 by default
1684
// may also return 0 if SYMCRYPT_FLAG_MODRANDOM_ALLOW_ZERO is specified
1685
// Modulo 3 => return 2 by default
1686
// may also return 1 if SYMCRYPT_FLAG_MODRANDOM_ALLOW_ONE is specified, and
1687
// may also return 0 or 1 if SYMCRYPT_FLAG_MODRANDOM_ALLOW_ZERO is specified,
1688
//
1689
// Callers relying on not having 0, 1, or -1 are required to pass a larger modulus.
1690
1691
#define SYMCRYPT_FLAG_MODRANDOM_ALLOW_ZERO (0x01)
1692
#define SYMCRYPT_FLAG_MODRANDOM_ALLOW_ONE (0x02)
1693
#define SYMCRYPT_FLAG_MODRANDOM_ALLOW_MINUSONE (0x04)
1694
1695
1696
VOID
1697
SYMCRYPT_CALL
1698
SymCryptModNeg(
1699
_In_ PCSYMCRYPT_MODULUS pmMod,
1700
_In_ PCSYMCRYPT_MODELEMENT peSrc,
1701
_Out_ PSYMCRYPT_MODELEMENT peDst,
1702
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1703
SIZE_T cbScratch );
1704
//
1705
// Dst = -Src mod Mod
1706
// Requirements:
1707
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1708
//
1709
1710
VOID
1711
SYMCRYPT_CALL
1712
SymCryptModAdd(
1713
_In_ PCSYMCRYPT_MODULUS pmMod,
1714
_In_ PCSYMCRYPT_MODELEMENT peSrc1,
1715
_In_ PCSYMCRYPT_MODELEMENT peSrc2,
1716
_Out_ PSYMCRYPT_MODELEMENT peDst,
1717
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1718
SIZE_T cbScratch );
1719
//
1720
// Dst = Src1 + Src2 mod Mod
1721
// Requirement:
1722
// - Src1.modulus == Src2.modulus == Mod.
1723
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1724
// Dst == Src1, Dst == Src2, and Src1 == Src2 are all allowed.
1725
// Rationale:
1726
// scratch space can make the mod-add faster for side-channel safe implementations.
1727
// It allows:
1728
// Dst = Src1 + Src2;
1729
// Tmp = Dst - Mod;
1730
// Dst = choose( Dst, Tmp, carry_bits )
1731
// And the choose() operation is fast because it does not require carry propagation.
1732
//
1733
1734
1735
VOID
1736
SYMCRYPT_CALL
1737
SymCryptModSub(
1738
_In_ PCSYMCRYPT_MODULUS pmMod,
1739
_In_ PCSYMCRYPT_MODELEMENT peSrc1,
1740
_In_ PCSYMCRYPT_MODELEMENT peSrc2,
1741
_Out_ PSYMCRYPT_MODELEMENT peDst,
1742
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1743
SIZE_T cbScratch );
1744
//
1745
// Dst = Src1 - Src2 mod Mod
1746
// Requirement:
1747
// Same as SymCryptModAdd
1748
//
1749
1750
1751
VOID
1752
SYMCRYPT_CALL
1753
SymCryptModMul(
1754
_In_ PCSYMCRYPT_MODULUS pmMod,
1755
_In_ PCSYMCRYPT_MODELEMENT peSrc1,
1756
_In_ PCSYMCRYPT_MODELEMENT peSrc2,
1757
_Out_ PSYMCRYPT_MODELEMENT peDst,
1758
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1759
SIZE_T cbScratch );
1760
//
1761
// Dst = Src1 * Src2 mod Mod
1762
// Requirement:
1763
// - Src1.modulus == Src2.modulus == Mod.
1764
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1765
//
1766
1767
VOID
1768
SYMCRYPT_CALL
1769
SymCryptModSquare(
1770
_In_ PCSYMCRYPT_MODULUS pmMod,
1771
_In_ PCSYMCRYPT_MODELEMENT peSrc,
1772
_Out_ PSYMCRYPT_MODELEMENT peDst,
1773
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1774
SIZE_T cbScratch );
1775
//
1776
// Dst = Src1^2 mod Mod
1777
// Requirement:
1778
// - Src.modulus == Mod.
1779
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1780
//
1781
1782
VOID
1783
SYMCRYPT_CALL
1784
SymCryptModDivPow2(
1785
_In_ PCSYMCRYPT_MODULUS pmMod,
1786
_In_ PCSYMCRYPT_MODELEMENT peSrc,
1787
UINT32 exp,
1788
_Out_ PSYMCRYPT_MODELEMENT peDst,
1789
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1790
SIZE_T cbScratch );
1791
//
1792
// Dst = Src / 2^exp mod Mod
1793
// Requirements:
1794
// - Mod is odd.
1795
// - Src.modulus == Dst.modulus == Mod.
1796
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( Mod.nDigits )
1797
//
1798
// Remarks:
1799
// - The value exp is *** public ***; hence it should be treated as known to the attacker.
1800
// - This function may write intermediate values to peDst and read them back, violating the
1801
// read-once/write-once rule, so the caller must ensure that the peDst buffer is trusted.
1802
//
1803
1804
#define SYMCRYPT_SCRATCH_BYTES_FOR_MODINV( _nDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_MODINV( _nDigits )
1805
1806
// SYMCRYPT_FLAG_DATA_PUBLIC signals that the Src element is public and does not have to be protected
1807
// against side-channel attacks. The public-ness of the Modulus is part of the Modulus object, specified when the
1808
// modulus value was set.
1809
// Marking the source value as public has very little effect on performance, but it removes the random blinding used.
1810
// The main goal of this flag is to allow ECDSA verification without a source of random numbers.
1811
1812
SYMCRYPT_ERROR
1813
SYMCRYPT_CALL
1814
SymCryptModInv(
1815
_In_ PCSYMCRYPT_MODULUS pmMod,
1816
_In_ PCSYMCRYPT_MODELEMENT peSrc,
1817
_Out_ PSYMCRYPT_MODELEMENT peDst,
1818
UINT32 flags,
1819
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1820
SIZE_T cbScratch );
1821
//
1822
// Dst = 1/Src mod Mod.
1823
//
1824
// - pmMod: Modulus, must have the SYMCRYPT_FLAG_MODULUS_PRIME and SYMCRYPT_FLAG_DATA_PUBLIC flag set.
1825
// Non-prime or non-public moduli are currently not supported.
1826
// - peSrc: Source value, modulo pmMod
1827
// - peDst: Destination value, mod element modulo pmMod
1828
// - flags: SYMCRYPT_FLAG_DATA_PUBLIC signals that peSrc is a public value.
1829
// - pbScratch/cbScratch: scratch space >= SYMCRYPT_SCRATCH_BYTES_FOR_MODINV( nDigits( pmMod ) )
1830
//
1831
// Returns an error if
1832
// - GCD( Src, Mod ) != 1
1833
//
1834
1835
#define SYMCRYPT_SCRATCH_BYTES_FOR_MODEXP( _nDigits ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_MODEXP( _nDigits )
1836
1837
VOID
1838
SYMCRYPT_CALL
1839
SymCryptModExp(
1840
_In_ PCSYMCRYPT_MODULUS pmMod,
1841
_In_ PCSYMCRYPT_MODELEMENT peBase,
1842
_In_ PCSYMCRYPT_INT piExp,
1843
UINT32 nBitsExp,
1844
UINT32 flags,
1845
_Out_ PSYMCRYPT_MODELEMENT peDst,
1846
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1847
SIZE_T cbScratch );
1848
//
1849
// Dst = Base ^ Exp mod Mod
1850
// where only the least significant (nBitsExp) bits of the exponent are used.
1851
//
1852
// Requirements:
1853
// - nBitsExp != 0
1854
// - Mod > 1
1855
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_MODEXP( Mod.nDigits )
1856
//
1857
// Allowed flags:
1858
// SYMCRYPT_FLAG_DATA_PUBLIC: If set then the algorithm
1859
// is not side-channel safe (For use in RSA encryption - exponentiation
1860
// with a public exponent). The default behaviour is side channel safety.
1861
//
1862
// Remarks:
1863
// - The undefined operation 0^0 will return 1.
1864
// - The value nBitsExp is *** public ***; hence it should be treated as known to the attacker.
1865
// Examples:
1866
// - nBitsExp = SymCryptIntBitsizeOfObject( piExp ) => This processes all the
1867
// bits of the exponent object.
1868
// - nBitsExp = number of bits of modulus ==> This processes the same
1869
// number of bits (even leading zeros) as the modulus. In this case
1870
// the exponent should have a value with bitsize less or equal to the
1871
// bitsize of the modulus.
1872
// - nBitsExp = max(1, SymCryptIntBitsizeOfValue( piExp )) => This processes
1873
// the bits of the exponent ignoring the leading zeros. Therefore, this
1874
// option leaks the bitsize of the value of the exponent.
1875
//
1876
1877
// SYMCRYPT_MODMULTIEXP_MAX_NBASES, _NBITSEXP: The maximum number of bases
1878
// and exponent bits allowed for the multi-exponentiation operation.
1879
#define SYMCRYPT_MODMULTIEXP_MAX_NBASES (8)
1880
#define SYMCRYPT_MODMULTIEXP_MAX_NBITSEXP (SYMCRYPT_INT_MAX_BITS)
1881
1882
#define SYMCRYPT_SCRATCH_BYTES_FOR_MODMULTIEXP( _nDigits, _nBases, _nBitsExp ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_MODMULTIEXP( _nDigits, _nBases, _nBitsExp )
1883
1884
SYMCRYPT_ERROR
1885
SYMCRYPT_CALL
1886
SymCryptModMultiExp(
1887
_In_ PCSYMCRYPT_MODULUS pmMod,
1888
_In_reads_( nBases ) PCSYMCRYPT_MODELEMENT * peBaseArray,
1889
_In_reads_( nBases ) PCSYMCRYPT_INT * piExpArray,
1890
UINT32 nBases,
1891
UINT32 nBitsExp,
1892
UINT32 flags,
1893
_Out_ PSYMCRYPT_MODELEMENT peDst,
1894
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
1895
SIZE_T cbScratch );
1896
//
1897
// Dst = ( peBaseArray[0]^piExpArray[0] * peBaseArray[1]^piExpArray[1] * ... *
1898
// peBaseArray[nBases-1]^piExpArray[nBases-1] ) mod Mod
1899
// where only the least significant (nBitsExp) bits of the exponents are used.
1900
//
1901
// Requirements:
1902
// - 1<= nBitsExp <= SYMCRYPT_MODMULTIEXP_MAX_NBITSEXP
1903
// - Mod > 1
1904
// - 1<= nBases <= SYMCRYPT_MODMULTIEXP_MAX_NBASES
1905
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_MODMULTIEXP( Mod.nDigits, nBases, nBitsExp )
1906
//
1907
// Allowed flags:
1908
// SYMCRYPT_FLAG_DATA_PUBLIC: If set then the algorithm
1909
// is not side-channel safe (For use in DSA verification).
1910
// The default behaviour is side channel safety.
1911
//
1912
1913
// =========================================
1914
// Tools for side-channel safety
1915
// ========================================
1916
1917
//
1918
//Side-channel safe lookup table
1919
//
1920
1921
typedef struct _SYMCRYPT_SCSTABLE {
1922
UINT32 groupSize;
1923
UINT32 interleaveSize;
1924
UINT32 nElements; // must be multiple of groupSize
1925
UINT32 elementSize; // # bytes in each element, note: limited to UINT32 for efficiency
1926
PBYTE pbTableData;
1927
UINT32 cbTableData;
1928
} SYMCRYPT_SCSTABLE, *PSYMCRYPT_SCSTABLE;
1929
1930
UINT32
1931
SYMCRYPT_CALL
1932
SymCryptScsTableInit(
1933
_Out_ PSYMCRYPT_SCSTABLE pScsTable,
1934
UINT32 nElements,
1935
UINT32 elementSize );
1936
// Initializes an ScsTable for nElements elements each of elementSize bytes.
1937
// nElements and elementSize are limited to less than 2^16.
1938
// Return value is the size of the buffer that the caller needs to provide.
1939
//
1940
// Requirements:
1941
// - nElements must be a multiple of groupSize and elementSize must be a
1942
// multiple of interleaveSize. Currently all implementations have as
1943
// defaults
1944
// groupSize = 4
1945
// interleaveSize = 8
1946
//
1947
1948
VOID
1949
SYMCRYPT_CALL
1950
SymCryptScsTableSetBuffer(
1951
_Inout_ PSYMCRYPT_SCSTABLE pScsTable,
1952
_Inout_updates_bytes_( cbBuffer ) PBYTE pbBuffer,
1953
UINT32 cbBuffer );
1954
// Sets the caller-provided buffer on the ScsTable.
1955
// cbBuffer should be >= the size returned by the SymCryptScsTableInit function
1956
1957
VOID
1958
SYMCRYPT_CALL
1959
SymCryptScsTableStore(
1960
_Inout_ PSYMCRYPT_SCSTABLE pScsTable,
1961
UINT32 iIndex,
1962
_In_reads_bytes_( cbData ) PCBYTE pbData,
1963
UINT32 cbData );
1964
// Not side-channel safe; publishes iIndex.
1965
// cbData must match the elementSize i.e. the size of a single element.
1966
1967
VOID
1968
SYMCRYPT_CALL
1969
SymCryptScsTableLoad(
1970
_In_ PSYMCRYPT_SCSTABLE pScsTable,
1971
UINT32 iIndex,
1972
_Out_writes_bytes_(cbData) PBYTE pbData,
1973
UINT32 cbData );
1974
// Side-channel safe fetching of data; iIndex is kept secret.
1975
// cbData must match the elementSize i.e. the size of a single element.
1976
1977
VOID
1978
SYMCRYPT_CALL
1979
SymCryptScsTableWipe(
1980
_Inout_ PSYMCRYPT_SCSTABLE pScsTable );
1981
// Wipes the part of the buffer that the table used
1982
1983
// Other Side-channel safety tools
1984
1985
VOID
1986
SYMCRYPT_CALL
1987
SymCryptScsRotateBuffer(
1988
_Inout_updates_( cbBuffer ) PBYTE pbBuffer,
1989
SIZE_T cbBuffer,
1990
SIZE_T lshift );
1991
// Rotates buffer left by lshift without revealing lshift
1992
// through side channels.
1993
// - pbBuffer/cbBuffer: buffer to rotate
1994
// pbBuffer must be aligned to the native integer of the platform (4 or 8 bytes)
1995
// cbBuffer must be a power of two >= 32
1996
// - lshift: # bytes to left rotate the buffer
1997
// pbBuffer[0] will get the value pbBuffer[ lshift % cbBuffer ]
1998
1999
VOID
2000
SYMCRYPT_CALL
2001
SymCryptScsCopy(
2002
_In_reads_( cbDst ) PCBYTE pbSrc,
2003
SIZE_T cbSrc,
2004
_Out_writes_( cbDst ) PBYTE pbDst,
2005
SIZE_T cbDst );
2006
// Copy cbSrc bytes of pbSrc into pbDst without revealing cbSrc
2007
// through side channels.
2008
//
2009
// WARNING: pbSrc buffer must be at least cbDst bytes long; not cbSrc!
2010
//
2011
// - pbSrc pointer to buffer to copy data from
2012
// This buffer must be at least cbDst bytes long
2013
// - cbSrc number of bytes to be copied, must be <= 2^31
2014
// - pbDst destination buffer
2015
// - pbDst size of the destination buffer, must be <= 2^31
2016
// Equivalent to:
2017
// n = min( cbSrc, cbDst )
2018
// pbDst[ 0.. n-1 ] = pbSrc[ 0 .. n - 1 ]
2019
// cbSrc is protected from side-channels; cbDst is public.
2020
2021
2022
//
2023
// Mask generation functions.
2024
// All these functions are side-channel safe in all parameters.
2025
// Naming convention:
2026
// SymCrypt <MaskType> <Op> <ParameterType>
2027
// <MaskType> is the type of the function result:
2028
// Mask32 UINT32 mask that is 0 or -1
2029
// Mask64 UINT64 mask that is 0 or -1
2030
// <Op> is the boolean operation performed on the parameters
2031
// IsZero v == 0
2032
// IsNonzero v != 0
2033
// Eq a == b
2034
// Neq a != b
2035
// <ParameterType> is an indication of the parameter type supported.
2036
// U31 UINT32 which is limited to values < 2^31
2037
// This allows more efficient masking functions.
2038
// U32 UINT32
2039
// Other mask types, operations, and parameter types may be defined in future.
2040
//
2041
2042
UINT32
2043
SYMCRYPT_CALL
2044
SymCryptMask32IsZeroU31( UINT32 v );
2045
2046
UINT32
2047
SYMCRYPT_CALL
2048
SymCryptMask32IsNonzeroU31( UINT32 v );
2049
2050
2051
UINT32
2052
SYMCRYPT_CALL
2053
SymCryptMask32EqU32( UINT32 a, UINT32 b );
2054
2055
UINT32
2056
SYMCRYPT_CALL
2057
SymCryptMask32NeqU31( UINT32 a, UINT32 b );
2058
2059
UINT32
2060
SYMCRYPT_CALL
2061
SymCryptMask32LtU31( UINT32 a, UINT32 b );
2062
2063
2064
//
2065
// Other helper functions
2066
//
2067
SIZE_T
2068
SYMCRYPT_CALL
2069
SymCryptRoundUpPow2Sizet( SIZE_T v );
2070
// Round up to the next power of 2
2071
//
2072
// Requirements:
2073
// v <= (SIZE_T_MAX / 2) + 1
2074
// i.e. rounding v up to the next power of 2 fits within SIZE_T, so v is
2075
// less than or equal to the maximum power of 2 representable in SIZE_T
2076
2077
2078
//=====================================================
2079
//=====================================================
2080
// RSA padding operations
2081
//=====================================================
2082
//=====================================================
2083
2084
SYMCRYPT_ERROR
2085
SYMCRYPT_CALL
2086
SymCryptRsaPkcs1ApplyEncryptionPadding(
2087
_In_reads_bytes_( cbPlaintext ) PCBYTE pbPlaintext,
2088
SIZE_T cbPlaintext,
2089
_Out_writes_bytes_( cbPkcs1Format ) PBYTE pbPkcs1Format,
2090
SIZE_T cbPkcs1Format );
2091
//
2092
// Applies the RSA PKCS1 v1.5 encryption padding to the plaintext buffer.
2093
// - Plaintext buffer containing plaintext to be encoded
2094
// - Pkcs1Format Output buffer, typically the size of the RSA modulus
2095
// Requirement: cbPkcs1Format >= cbPlaintext + 11 due to the PKCS1 overhead.
2096
//
2097
2098
SYMCRYPT_ERROR
2099
SYMCRYPT_CALL
2100
SymCryptRsaPkcs1RemoveEncryptionPadding(
2101
_Inout_updates_bytes_( cbPkcs1Buffer ) PBYTE pbPkcs1Format,
2102
SIZE_T cbPkcs1Format,
2103
SIZE_T cbPkcs1Buffer,
2104
_Out_writes_bytes_opt_( cbPlaintext ) PBYTE pbPlaintext,
2105
SIZE_T cbPlaintext,
2106
_Out_ SIZE_T *pcbPlaintext );
2107
//
2108
// Remove the PKCS1 encryption padding and extract the message plaintext.
2109
// This function is side-channel safe w.r.t. the data in the Pkcs1Format buffer.
2110
// - pbPkcs1Format points to a buffer containing the raw RSA decrypted data.
2111
// This buffer will be modified by this function.
2112
// - cbPkcs1Format is the # bytes of the buffer that were decrypted with raw RSA
2113
// - cbPkcs1Buffer is the size of the buffer that pbPkcs1Format points to
2114
// cbPkcs1Buffer must be a power of 2 and >= cbPkcs1Format and >= 32
2115
// cbPkcs1Buffer must be <= 2^30
2116
// - pbPlaintext/cbPlaintext is the output buffer that will receive the data.
2117
// if pbPlaintext == NULL no message is output, but *pcbPlaintext is still set.
2118
// - pcbPlaintext receives the # bytes in the actual decrypted message.
2119
// set to 0 if an error occurred.
2120
//
2121
2122
#define SYMCRYPT_SCRATCH_BYTES_FOR_RSA_OAEP( _hashAlgorithm, _nBytesOAEP ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_RSA_OAEP( _hashAlgorithm, _nBytesOAEP )
2123
2124
SYMCRYPT_ERROR
2125
SYMCRYPT_CALL
2126
SymCryptRsaOaepApplyEncryptionPadding(
2127
_In_reads_bytes_( cbPlaintext ) PCBYTE pbPlaintext,
2128
SIZE_T cbPlaintext,
2129
_In_ PCSYMCRYPT_HASH hashAlgorithm,
2130
_In_reads_bytes_( cbLabel ) PCBYTE pbLabel,
2131
SIZE_T cbLabel,
2132
_In_reads_bytes_opt_( cbSeed ) PCBYTE pbSeed,
2133
SIZE_T cbSeed,
2134
_Out_writes_bytes_( cbOaepFormat ) PBYTE pbOaepFormat,
2135
SIZE_T cbOaepFormat,
2136
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
2137
SIZE_T cbScratch );
2138
//
2139
// Apply the RSA OAEP encryption padding to the plaintext buffer.
2140
// - Plaintext Plaintext to be encoded
2141
// - hashAlgorithm Hash algorithm to use during padding
2142
// - Label Label input for OAEP
2143
// - Seed Specified seed value. 0 <= cbSeed < hash size
2144
// - OaepFormat Output buffer, typically the size of the RSA modulus
2145
//
2146
// Remarks:
2147
// - If pbSeed == NULL and cbSeed != 0, then the function picks
2148
// a uniformly random seed of size cbSeed bytes.
2149
//
2150
// Requirements:
2151
// cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_RSA_OAEP( hashAlgorithm, cbOAEPFormat )
2152
//
2153
2154
SYMCRYPT_ERROR
2155
SYMCRYPT_CALL
2156
SymCryptRsaOaepRemoveEncryptionPadding(
2157
_In_reads_bytes_( cbOAEPFormat )
2158
PCBYTE pbOAEPFormat,
2159
SIZE_T cbOAEPFormat,
2160
_In_ PCSYMCRYPT_HASH hashAlgorithm,
2161
_In_reads_bytes_( cbLabel ) PCBYTE pbLabel,
2162
SIZE_T cbLabel,
2163
UINT32 flags,
2164
_Out_writes_bytes_( cbPlaintext )
2165
PBYTE pbPlaintext,
2166
SIZE_T cbPlaintext,
2167
_Out_ SIZE_T *pcbPlaintext,
2168
_Out_writes_bytes_( cbScratch )
2169
PBYTE pbScratch,
2170
SIZE_T cbScratch );
2171
//
2172
// Removes the RSA OAEP encryption padding from the OAEP formatted buffer
2173
// after it checks the validity of the format.
2174
//
2175
// *pcbPlaintext is the number of bytes output. If pbPlaintext == NULL then this
2176
// is the only output value.
2177
//
2178
// Allowed flags:
2179
// None
2180
//
2181
// Requirements:
2182
// cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_RSA_OAEP( hashAlgorithm, cbOAEPFormat )
2183
//
2184
2185
#define SYMCRYPT_SCRATCH_BYTES_FOR_RSA_PKCS1( _nBytesPKCS1 ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_RSA_PKCS1( _nBytesPKCS1 )
2186
2187
SYMCRYPT_ERROR
2188
SYMCRYPT_CALL
2189
SymCryptRsaPkcs1ApplySignaturePadding(
2190
_In_reads_bytes_( cbHash ) PCBYTE pbHash,
2191
SIZE_T cbHash,
2192
_In_reads_bytes_( cbHashOid )
2193
PCBYTE pbHashOid,
2194
SIZE_T cbHashOid,
2195
UINT32 flags,
2196
_Out_writes_bytes_( cbPKCS1Format )
2197
PBYTE pbPKCS1Format,
2198
SIZE_T cbPKCS1Format );
2199
//
2200
// Applies the RSA PKCS1 v1.5 signature padding to the source buffer, which typically contains the
2201
// hash of the message.
2202
//
2203
// Allowed flags:
2204
// SYMCRYPT_FLAG_RSA_PKCS1_NO_ASN1
2205
//
2206
2207
SYMCRYPT_ERROR
2208
SYMCRYPT_CALL
2209
SymCryptRsaPkcs1VerifySignaturePadding(
2210
_In_reads_bytes_( cbHash ) PCBYTE pbHash,
2211
SIZE_T cbHash,
2212
_In_reads_( nOIDCount ) PCSYMCRYPT_OID pHashOIDs,
2213
_In_ SIZE_T nOIDCount,
2214
_In_reads_bytes_( cbPKCS1Format )
2215
PCBYTE pbPKCS1Format,
2216
SIZE_T cbPKCS1Format,
2217
UINT32 flags,
2218
_Out_writes_bytes_( cbScratch )
2219
PBYTE pbScratch,
2220
SIZE_T cbScratch );
2221
//
2222
// Verifies that the RSA PKCS1 v1.5 signature padding is valid.
2223
//
2224
// It returns SYMCRYPT_NO_ERROR if the verification succeeded or SYMCRYPT_VERIFICATION_FAIL
2225
// if it failed.
2226
//
2227
// Allowed flags:
2228
// SYMCRYPT_FLAG_RSA_PKCS1_OPTIONAL_HASH_OID
2229
//
2230
// Requirements:
2231
// cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_RSA_PKCS1( cbPKCS1Format )
2232
//
2233
2234
#define SYMCRYPT_SCRATCH_BYTES_FOR_RSA_PSS( _hashAlgorithm, _nBytesMessage, _nBytesPSS ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_RSA_PSS( _hashAlgorithm, _nBytesMessage, _nBytesPSS )
2235
2236
SYMCRYPT_ERROR
2237
SYMCRYPT_CALL
2238
SymCryptRsaPssApplySignaturePadding(
2239
_In_reads_bytes_( cbHash ) PCBYTE pbHash,
2240
SIZE_T cbHash,
2241
_In_ PCSYMCRYPT_HASH hashAlgorithm,
2242
_In_reads_bytes_opt_( cbSalt )
2243
PCBYTE pbSalt,
2244
_In_range_(0, cbPSSFormat) SIZE_T cbSalt,
2245
UINT32 nBitsOfModulus,
2246
UINT32 flags,
2247
_Out_writes_bytes_( cbPSSFormat )
2248
PBYTE pbPSSFormat,
2249
SIZE_T cbPSSFormat,
2250
_Out_writes_bytes_( cbScratch )
2251
PBYTE pbScratch,
2252
SIZE_T cbScratch );
2253
//
2254
// Applies the RSA PSS signature padding to the source buffer, which typically contains the
2255
// hash of the message.
2256
//
2257
// Remarks:
2258
// - If pbSalt == NULL and cbSalt != 0, then the function picks
2259
// a uniformly random salt of size cbSalt bytes.
2260
//
2261
// Allowed flags:
2262
// None
2263
//
2264
// Requirements:
2265
// cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_RSA_PSS( hashAlgorithm, cbHash, cbPSSFormat )
2266
//
2267
2268
SYMCRYPT_ERROR
2269
SYMCRYPT_CALL
2270
SymCryptRsaPssVerifySignaturePadding(
2271
_In_reads_bytes_( cbHash ) PCBYTE pbHash,
2272
SIZE_T cbHash,
2273
_In_ PCSYMCRYPT_HASH hashAlgorithm,
2274
_In_range_(0, cbPSSFormat) SIZE_T cbSalt,
2275
_In_reads_bytes_( cbPSSFormat )
2276
PCBYTE pbPSSFormat,
2277
SIZE_T cbPSSFormat,
2278
UINT32 nBitsOfModulus,
2279
UINT32 flags,
2280
_Out_writes_bytes_( cbScratch )
2281
PBYTE pbScratch,
2282
SIZE_T cbScratch );
2283
//
2284
// Verifies that the RSA PSS signature padding is valid.
2285
//
2286
// It returns SYMCRYPT_NO_ERROR if the verification succeeded or SYMCRYPT_VERIFICATION_FAIL
2287
// if it failed.
2288
//
2289
// Allowed flags:
2290
// SYMCRYPT_FLAG_RSA_PSS_VERIFY_WITH_MINIMUM_SALT
2291
//
2292
// When the flag is set, this function will do signature verification using the cbSalt parameter as
2293
// a minimum value for the salt length, rather than using it as an exact value. Specifying this and
2294
// setting cbSalt = 0 allows callers to verify a signature which has a valid encoding with any salt
2295
// length using a single call.
2296
//
2297
//
2298
// Requirements:
2299
// cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_RSA_PSS( hashAlgorithm, cbHash, cbPSSFormat )
2300
//
2301
2302
//=====================================================
2303
//=====================================================
2304
// EC point operations
2305
//=====================================================
2306
//=====================================================
2307
2308
PCSYMCRYPT_MODULUS
2309
SYMCRYPT_CALL
2310
SymCryptEcurveGroupOrder( _In_ PCSYMCRYPT_ECURVE pCurve );
2311
//
2312
// This function returns a pointer to the group order of the curve's subgroup.
2313
//
2314
2315
UINT32
2316
SYMCRYPT_CALL
2317
SymCryptEcurveDigitsofScalarMultiplier( _In_ PCSYMCRYPT_ECURVE pCurve );
2318
//
2319
// This function returns the number of digits of a scalar that is big enough to
2320
// store a multiplier of an elliptic curve point.
2321
// See also, SymCryptEcurveSizeofScalarMultiplier.
2322
//
2323
2324
UINT32
2325
SYMCRYPT_CALL
2326
SymCryptEcurveDigitsofFieldElement( _In_ PCSYMCRYPT_ECURVE pCurve );
2327
//
2328
// This function returns the number of digits for one coordinate of the public key.
2329
//
2330
2331
//=====================================================
2332
// GETSET_VALUE_ECURVE_OPERATIONS
2333
//
2334
2335
#define SYMCRYPT_SCRATCH_BYTES_FOR_GETSET_VALUE_ECURVE_OPERATIONS( _pCurve ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_GETSET_VALUE_ECURVE_OPERATIONS( _pCurve )
2336
2337
SYMCRYPT_ERROR
2338
SYMCRYPT_CALL
2339
SymCryptEcpointSetValue(
2340
_In_ PCSYMCRYPT_ECURVE pCurve,
2341
_In_reads_bytes_(cbSrc) PCBYTE pbSrc,
2342
SIZE_T cbSrc,
2343
SYMCRYPT_NUMBER_FORMAT nformat,
2344
SYMCRYPT_ECPOINT_FORMAT eformat,
2345
_Out_ PSYMCRYPT_ECPOINT poDst,
2346
UINT32 flags,
2347
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
2348
SIZE_T cbScratch );
2349
//
2350
// Set the value of an ECPOINT object from a source buffer pbSrc of size cbSrc. The buffer
2351
// will contain the necessary coordinates of the ECPOINT in the format specified by nformat
2352
// and eformat. The nformat determines the format of the integers in the buffer while the
2353
// eformat determines the layout (and the number) of the coordinates.
2354
//
2355
// Requirements:
2356
// - cbSrc = X * SymCryptEcurveSizeofFieldElement( pCurve ) where X depends on the
2357
// eformat specified and denotes the number of coordinates. For example, for
2358
// SYMCRYPT_ECPOINT_FORMAT_XY it is equal to 2.
2359
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_GETSET_VALUE_ECURVE_OPERATIONS( pCurve )
2360
//
2361
// Flag values:
2362
// SYMCRYPT_FLAG_DATA_PUBLIC data is public (no side-channel protection needed)
2363
//
2364
// Rationale:
2365
// Scratch space provides room for conversion of point representations.
2366
//
2367
// Example:
2368
// Set an ECPOINT to (X,Y) point in affine coordinates where the size of each coordinate
2369
// is t = SymCryptEcurveSizeofFieldElement( pCurve ) bytes. The coordinates are
2370
// X=(X_(t-1), ... , X_1, X_0) and Y=(Y_(t-1), ... , Y_1, Y_0) with t-1 the
2371
// most significant byte. Then the function can be called with
2372
// pbSrc = { X_(t-1), ... , X_1, X_0, Y_(t-1), ... , Y_1, Y_0 }
2373
// cbSrc = 2 * t
2374
// nformat = SYMCRYPT_NUMBER_FORMAT_MSB_FIRST
2375
// eformat = SYMCRYPT_ECPOINT_FORMAT_XY
2376
//
2377
2378
SYMCRYPT_ERROR
2379
SYMCRYPT_CALL
2380
SymCryptEcpointGetValue(
2381
_In_ PCSYMCRYPT_ECURVE pCurve,
2382
_In_ PCSYMCRYPT_ECPOINT poSrc,
2383
SYMCRYPT_NUMBER_FORMAT nformat,
2384
SYMCRYPT_ECPOINT_FORMAT eformat,
2385
_Out_writes_bytes_(cbDst) PBYTE pbDst,
2386
SIZE_T cbDst,
2387
UINT32 flags,
2388
_Out_writes_bytes_( cbScratch ) PBYTE pbScratch,
2389
SIZE_T cbScratch );
2390
//
2391
// Retrieve the value of an ECPOINT object into a destination buffer pbDst of size cbDst. The buffer
2392
// will contain the necessary coordinates of the ECPOINT in the format specified by nformat
2393
// and eformat. The nformat determines the format of the integers in the buffer while the
2394
// eformat determines the layout (and the number) of the coordinates.
2395
//
2396
// Flag values:
2397
// SYMCRYPT_FLAG_DATA_PUBLIC data is public (no side-channel protection needed)
2398
//
2399
// Remarks:
2400
// - If the source point is the "zero" point and it cannot be exported into the
2401
// required ECPOINT_FORMAT (XY or X), the function fails with SYMCRYPT_INCOMPATIBLE_FORMAT.
2402
//
2403
// Requirements:
2404
// - cbDst = X * SymCryptEcurveSizeofFieldElement( pCurve ) where X depends on the
2405
// eformat specified and denotes the number of coordinates. For example for SYMCRYPT_ECPOINT_FORMAT_XY it is equal to 2.
2406
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_GETSET_VALUE_ECURVE_OPERATIONS( pCurve )
2407
//
2408
// Rationale:
2409
// Scratch space provides room for conversion of point representations.
2410
//
2411
2412
//
2413
// Low-level flags for ECC operations
2414
//
2415
// SYMCRYPT_FLAG_DATA_PUBLIC: When set, the operation will not be side-channel safe.
2416
// It is used to speed up operation on public data. (default: side-channel safe)
2417
//
2418
// SYMCRYPT_FLAG_ECC_LL_COFACTOR_MUL: When set, the underlying operation will multiply
2419
// by the cofactor of the curve. (default: no multiplication by the cofactor)
2420
// Remark: **Notice that the default behaviour is the opposite of the higher-level
2421
// functions in symcrypt.h.**
2422
#define SYMCRYPT_FLAG_ECC_LL_COFACTOR_MUL (0x20)
2423
2424
//=====================================================
2425
// COMMON_ECURVE_OPERATIONS
2426
//
2427
2428
#define SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( _pCurve ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( _pCurve )
2429
2430
VOID
2431
SYMCRYPT_CALL
2432
SymCryptEcpointSetZero(
2433
_In_ PCSYMCRYPT_ECURVE pCurve,
2434
_Out_ PSYMCRYPT_ECPOINT poDst,
2435
_Out_writes_bytes_opt_( cbScratch )
2436
PBYTE pbScratch,
2437
SIZE_T cbScratch );
2438
//
2439
// Set the destination point poDst to the zero
2440
// element of the additive group defined by the
2441
// elliptic curve addition rule.
2442
//
2443
// Requirements:
2444
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ).
2445
//
2446
2447
VOID
2448
SYMCRYPT_CALL
2449
SymCryptEcpointSetDistinguishedPoint(
2450
_In_ PCSYMCRYPT_ECURVE pCurve,
2451
_Out_ PSYMCRYPT_ECPOINT poDst,
2452
_Out_writes_bytes_opt_( cbScratch )
2453
PBYTE pbScratch,
2454
SIZE_T cbScratch );
2455
//
2456
// Set the destination point poDst to the
2457
// distinguished point of the curve.
2458
//
2459
// Requirements:
2460
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ).
2461
//
2462
2463
#define SYMCRYPT_FLAG_ECPOINT_EQUAL (0x01)
2464
#define SYMCRYPT_FLAG_ECPOINT_NEG_EQUAL (0x02)
2465
2466
UINT32
2467
SYMCRYPT_CALL
2468
SymCryptEcpointIsEqual(
2469
_In_ PCSYMCRYPT_ECURVE pCurve,
2470
_In_ PCSYMCRYPT_ECPOINT poSrc1,
2471
_In_ PCSYMCRYPT_ECPOINT poSrc2,
2472
UINT32 flags,
2473
_Out_writes_bytes_opt_( cbScratch )
2474
PBYTE pbScratch,
2475
SIZE_T cbScratch );
2476
//
2477
// If the flags argument is equal to 0 (default) or SYMCRYPT_FLAG_ECPOINT_EQUAL, it returns a mask value which is
2478
// 0xffffffff if poSrc1 = poSrc2 and 0 otherwise.
2479
// If the flags argument is equal to SYMCRYPT_FLAG_ECPOINT_NEG_EQUAL, it returns a mask value which is
2480
// 0xffffffff if poSrc1 = -poSrc2 and 0 otherwise.
2481
// If the flags argument is equal to SYMCRYPT_FLAG_ECPOINT_EQUAL | SYMCRYPT_FLAG_ECPOINT_NEG_EQUAL,
2482
// it returns a mask value which is 0xffffffff if (poSrc1 = poSrc2) or (poSrc1 = -poSrc2) and 0 otherwise.
2483
//
2484
// The points should have been created with the same curve pCurve. Otherwise the result is undefined.
2485
//
2486
// Requirements:
2487
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ).
2488
//
2489
2490
UINT32
2491
SYMCRYPT_CALL
2492
SymCryptEcpointIsZero(
2493
_In_ PCSYMCRYPT_ECURVE pCurve,
2494
_In_ PCSYMCRYPT_ECPOINT poSrc,
2495
_Out_writes_bytes_opt_( cbScratch )
2496
PBYTE pbScratch,
2497
SIZE_T cbScratch );
2498
//
2499
// Returns a mask value which is 0xffffffff if the point is the zero point of the group.
2500
//
2501
// Requirements:
2502
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ).
2503
//
2504
2505
UINT32
2506
SYMCRYPT_CALL
2507
SymCryptEcpointOnCurve(
2508
_In_ PCSYMCRYPT_ECURVE pCurve,
2509
_In_ PCSYMCRYPT_ECPOINT poSrc,
2510
_Out_writes_bytes_opt_( cbScratch )
2511
PBYTE pbScratch,
2512
SIZE_T cbScratch );
2513
//
2514
// Returns a mask value which is 0xffffffff if the point is on curve.
2515
//
2516
// Requirements:
2517
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ).
2518
//
2519
2520
VOID
2521
SYMCRYPT_CALL
2522
SymCryptEcpointAdd(
2523
_In_ PCSYMCRYPT_ECURVE pCurve,
2524
_In_ PCSYMCRYPT_ECPOINT poSrc1,
2525
_In_ PCSYMCRYPT_ECPOINT poSrc2,
2526
_Out_ PSYMCRYPT_ECPOINT poDst,
2527
UINT32 flags,
2528
_Out_writes_bytes_opt_( cbScratch )
2529
PBYTE pbScratch,
2530
SIZE_T cbScratch );
2531
//
2532
// Point addition over the curve pCurve.
2533
// poDst = poSrc1 + poSrc2
2534
//
2535
// Allowed flags:
2536
// SYMCRYPT_FLAG_DATA_PUBLIC: If set then the algorithm
2537
// is not side-channel safe (and faster). The default behaviour
2538
// is side-channel safety.
2539
//
2540
// Remarks:
2541
// - Complete (i.e. works for all points)
2542
// - Writes intermediate results to poDst breaking the read-once/write-once rule
2543
//
2544
// Requirements:
2545
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ).
2546
//
2547
2548
VOID
2549
SYMCRYPT_CALL
2550
SymCryptEcpointAddDiffNonZero(
2551
_In_ PCSYMCRYPT_ECURVE pCurve,
2552
_In_ PCSYMCRYPT_ECPOINT poSrc1,
2553
_In_ PCSYMCRYPT_ECPOINT poSrc2,
2554
_Out_ PSYMCRYPT_ECPOINT poDst,
2555
_Out_writes_bytes_opt_( cbScratch )
2556
PBYTE pbScratch,
2557
SIZE_T cbScratch );
2558
//
2559
// Point addition when *peSrc1 != +- *peSrc2
2560
// and none of them is equal to the zero point.
2561
//
2562
// Remarks:
2563
// - Side-channel safe
2564
// - Complete (i.e. works for all points)
2565
// - Writes intermediate results to poDst breaking the read-once/write-once rule
2566
//
2567
// Requirements:
2568
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ).
2569
//
2570
2571
VOID
2572
SYMCRYPT_CALL
2573
SymCryptEcpointDouble(
2574
_In_ PCSYMCRYPT_ECURVE pCurve,
2575
_In_ PCSYMCRYPT_ECPOINT poSrc,
2576
_Out_ PSYMCRYPT_ECPOINT poDst,
2577
UINT32 flags,
2578
_Out_writes_bytes_opt_( cbScratch )
2579
PBYTE pbScratch,
2580
SIZE_T cbScratch );
2581
//
2582
// Point doubling.
2583
//
2584
// Allowed flags:
2585
// SYMCRYPT_FLAG_DATA_PUBLIC: If set then the algorithm
2586
// is not side-channel safe (and faster). The default behaviour
2587
// is side-channel safety.
2588
//
2589
// Remarks:
2590
// - Side-channel safe
2591
// - Writes intermediate results to poDst breaking the read-once/write-once rule
2592
//
2593
// Requirements:
2594
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ).
2595
//
2596
2597
VOID
2598
SYMCRYPT_CALL
2599
SymCryptEcpointNegate(
2600
_In_ PCSYMCRYPT_ECURVE pCurve,
2601
_Inout_ PSYMCRYPT_ECPOINT poSrc,
2602
UINT32 mask,
2603
_Out_writes_bytes_opt_( cbScratch )
2604
PBYTE pbScratch,
2605
SIZE_T cbScratch );
2606
//
2607
// Negates (in place) the source point poSrc if mask == 0xffffffff.
2608
//
2609
// Requirements:
2610
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( pCurve ).
2611
//
2612
2613
//=====================================================
2614
// SCALAR_ECURVE_OPERATIONS
2615
//
2616
2617
#define SYMCRYPT_SCRATCH_BYTES_FOR_SCALAR_ECURVE_OPERATIONS( _pCurve ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_SCALAR_ECURVE_OPERATIONS( (_pCurve), 1 )
2618
#define SYMCRYPT_SCRATCH_BYTES_FOR_MULTI_SCALAR_ECURVE_OPERATIONS( _pCurve, _nPoints ) SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_SCALAR_ECURVE_OPERATIONS( (_pCurve), (_nPoints) )
2619
2620
VOID
2621
SYMCRYPT_CALL
2622
SymCryptEcpointSetRandom(
2623
_In_ PCSYMCRYPT_ECURVE pCurve,
2624
_Out_ PSYMCRYPT_INT piScalar,
2625
_Out_ PSYMCRYPT_ECPOINT poDst,
2626
_Out_writes_bytes_opt_( cbScratch )
2627
PBYTE pbScratch,
2628
SIZE_T cbScratch );
2629
//
2630
// Set the destination point poDst to a random non-zero point
2631
// of the subgroup generated by the distinguished point.
2632
// The function outputs the integer k and the point kG
2633
// where k is picked uniformly at random from the set
2634
// [1, SubgroupOrder-1] ( 0 is excluded).
2635
//
2636
// Requirements:
2637
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_SCALAR_ECURVE_OPERATIONS( pCurve ).
2638
//
2639
2640
SYMCRYPT_ERROR
2641
SYMCRYPT_CALL
2642
SymCryptEcpointScalarMul(
2643
_In_ PCSYMCRYPT_ECURVE pCurve,
2644
_In_ PCSYMCRYPT_INT piScalar,
2645
_In_opt_
2646
PCSYMCRYPT_ECPOINT poSrc,
2647
UINT32 flags,
2648
_Out_ PSYMCRYPT_ECPOINT poDst,
2649
_Out_writes_bytes_opt_( cbScratch )
2650
PBYTE pbScratch,
2651
SIZE_T cbScratch );
2652
//
2653
// Multiplication of point by scalar.
2654
// poDst = piScalar x poSrc
2655
//
2656
// If poSrc == NULL the algorithm uses the distinguished point of the curve as source
2657
// point and it might be faster (depending on the curve optimizations).
2658
//
2659
// Allowed flags:
2660
// SYMCRYPT_FLAG_ECC_LL_COFACTOR_MUL: If set then
2661
// the scalar is multiplied by the cofactor of
2662
// the curve. The default behaviour is to not multiply
2663
// by the cofactor.
2664
//
2665
// Remarks:
2666
// - Complete
2667
// - Side-channel safe
2668
//
2669
// Requirements:
2670
// - The piScalar must have SymCryptEcurveDigitsofScalarMultiplier( pCurve ) digits.
2671
// - For Non-Montgomery curves, the piScalar must be in the range [0, SubgroupOrder].
2672
// - This is the caller's responsibility, it is not checked.
2673
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_SCALAR_ECURVE_OPERATIONS( pCurve ).
2674
//
2675
2676
// SYMCRYPT_ECURVE_MULTI_SCALAR_MUL_MAX_NPOINTS: The maximum number of points allowed for the
2677
// multi-scalar multiplication operation.
2678
#define SYMCRYPT_ECURVE_MULTI_SCALAR_MUL_MAX_NPOINTS (2)
2679
2680
SYMCRYPT_ERROR
2681
SYMCRYPT_CALL
2682
SymCryptEcpointMultiScalarMul(
2683
_In_ PCSYMCRYPT_ECURVE pCurve,
2684
_In_ PCSYMCRYPT_INT * piSrcScalarArray,
2685
_In_ PCSYMCRYPT_ECPOINT * poSrcEcpointArray,
2686
UINT32 nPoints,
2687
UINT32 flags,
2688
_Out_ PSYMCRYPT_ECPOINT poDst,
2689
_Out_writes_bytes_opt_( cbScratch )
2690
PBYTE pbScratch,
2691
SIZE_T cbScratch );
2692
//
2693
// It executes the multi scalar - add operation for nPoints
2694
// pairs of (exponents, points) in (piSrcScalarArray, poSrcEcpointArray).
2695
//
2696
// If poSrcEcpointArray[0] == NULL the algorithm uses the distinguished point of the curve as
2697
// the first source point and it might be faster (depending on the curve optimizations).
2698
// Only the first source point can be NULL.
2699
//
2700
// Allowed flags:
2701
// SYMCRYPT_FLAG_ECC_LL_COFACTOR_MUL: If set then
2702
// the scalar is multiplied by the cofactor of
2703
// the curve. The default behaviour is to not multiply
2704
// by the cofactor.
2705
// SYMCRYPT_FLAG_DATA_PUBLIC: If set then the algorithm
2706
// is not side-channel safe (For use in the ECDSA
2707
// verification with public information). The default behaviour
2708
// is side channel safe.
2709
//
2710
// Requirements:
2711
// - 1<= nPoints <= SYMCRYPT_ECURVE_MULTI_SCALAR_MUL_MAX_NPOINTS
2712
// - Each piScalar must have SymCryptEcurveDigitsofScalarMultiplier( pCurve ) digits.
2713
// - cbScratch >= SYMCRYPT_SCRATCH_BYTES_FOR_MULTI_SCALAR_ECURVE_OPERATIONS( pCurve, nPoints ).
2714
//
2715
2716
2717
////////////////////////////////////////////////////////////////////////////
2718
// AES-CTR-DRBG
2719
//
2720
2721
#define SYMCRYPT_RNG_AES_INTERNAL_SEED_SIZE (32 + 16)
2722
2723
SYMCRYPT_ERROR
2724
SYMCRYPT_CALL
2725
SymCryptRngAesGenerateSmall(
2726
_Inout_ PSYMCRYPT_RNG_AES_STATE pRngState,
2727
_Out_writes_( cbRandom ) PBYTE pbRandom,
2728
SIZE_T cbRandom,
2729
_In_reads_opt_( cbAdditionalInput ) PCBYTE pbAdditionalInput,
2730
SIZE_T cbAdditionalInput );
2731
//
2732
// Generate random output from the state per SP 800-90.
2733
// Callers should almost always use SymCryptRngAesGenerate from symcrypt.h instead.
2734
//
2735
// This is the core generation function that produces up to 64 kB at a time
2736
// This function returns an error code so that we can test the
2737
// error handling of having done more than 2^48 requests between reseeds,
2738
// as required by SP 800-90.
2739
// This is also the Generate function of our SP800-90 compliant implementation.
2740
// If pRngState->fips140-2Check is true, this function runs the continuous self test
2741
// required by FIPS 140-2 (but not by FIPS 140-3 as far as we know).
2742
// pbAdditionalInput is optional.
2743
//
2744
2745
//=====================================================
2746
// ECDSA-EX
2747
//
2748
2749
SYMCRYPT_ERROR
2750
SYMCRYPT_CALL
2751
SymCryptEcDsaSignEx(
2752
_In_ PCSYMCRYPT_ECKEY pKey,
2753
_In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,
2754
SIZE_T cbHashValue,
2755
_In_opt_ PCSYMCRYPT_INT piK,
2756
SYMCRYPT_NUMBER_FORMAT format,
2757
UINT32 flags,
2758
_Out_writes_bytes_( cbSignature ) PBYTE pbSignature,
2759
SIZE_T cbSignature );
2760
//
2761
// This algorithm is the same as SymCryptEcDsaSign except that the caller can specify
2762
// a value of k in piK. It is used in verifying test vectors of ECDSA.
2763
//
2764
// Requirements:
2765
// - If piK is not NULL it must have SymCryptEcurveDigitsofScalarMultiplier( pCurve ) digits, and
2766
// must be in range [1, SubgroupOrder-1].
2767
// - If piK is not NULL and the generated signature would be 0, SYMCRYPT_INVALID_ARGUMENT is
2768
// returned.
2769
//
2770
// Allowed flags:
2771
// SYMCRYPT_FLAG_ECDSA_NO_TRUNCATION: If set then the hash value will
2772
// not be truncated.
2773
//
2774
// SYMCRYPT_FLAG_DATA_PUBLIC: If specified, all inputs, including the private key, are
2775
// considered as public information and are not protected against side channel attacks.
2776
// This should only be used when signing with a publicly known private key (i.e. in the ECDSA self-test)
2777
//
2778
2779
//=====================================================
2780
// ML-KEM-EX
2781
//
2782
2783
SYMCRYPT_ERROR
2784
SYMCRYPT_CALL
2785
SymCryptMlKemEncapsulateEx(
2786
_In_ PCSYMCRYPT_MLKEMKEY pkMlKemkey,
2787
_In_reads_bytes_( cbRandom ) PCBYTE pbRandom,
2788
SIZE_T cbRandom,
2789
_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,
2790
SIZE_T cbAgreedSecret,
2791
_Out_writes_bytes_( cbCiphertext ) PBYTE pbCiphertext,
2792
SIZE_T cbCiphertext );
2793
//
2794
// Performs the Encapsulate operation of ML-KEM using caller-provided random input.
2795
// It is used in verifying test vectors of ML-KEM.
2796
//
2797
// This uses the public information of an ML-KEM keypair to generate an agreed secret
2798
// and a ciphertext. Only a peer with the private information of an ML-KEM keypair can
2799
// decapsulate the ciphertext to compute the agreed secret.
2800
//
2801
// The arguments are the following:
2802
// - pkMlKemkey: a key which contains public information required for encapsulation.
2803
// - (pbRandom, cbRandom): a buffer containing the input random.
2804
// Currently cbRandom must be 32 for all parameterizations of ML-KEM.
2805
// - (pbAgreedSecret, cbAgreedSecret): a buffer into which the generated secret is written.
2806
// Currently cbAgreedSecret must be 32 for all parameterizations of ML-KEM.
2807
// - (pbCiphertext, cbCiphertext): a buffer into which the encapsulated secret is written.
2808
// cbCiphertext must equal cbCiphertext given by SymCryptMlKemSizeofCiphertextFromParams,
2809
// though typically this value can be known statically (see definition of
2810
// SYMCRYPT_MLKEM_CIPHERTEXT_SIZE_*).
2811
//
2812
2813
SYMCRYPT_ERROR
2814
SYMCRYPT_CALL
2815
SymCryptCompositeMlKemEncapsulateEx(
2816
_In_ PCSYMCRYPT_COMPOSITE_MLKEMKEY pkCompositeMlKemkey,
2817
_In_reads_bytes_opt_( cbMlKemRandom ) PCBYTE pbMlKemRandom,
2818
SIZE_T cbMlKemRandom,
2819
_In_reads_bytes_opt_( cbTradRandom ) PCBYTE pbTradRandom,
2820
SIZE_T cbTradRandom,
2821
_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,
2822
SIZE_T cbAgreedSecret,
2823
_Out_writes_bytes_( cbCiphertext ) PBYTE pbCiphertext,
2824
SIZE_T cbCiphertext );
2825
2826
//
2827
// Performs the Encapsulate operation of Composite ML-KEM using caller-provided random input.
2828
// It is used in verifying test vectors of Composite ML-KEM.
2829
//
2830
// This uses the public information of a Composite ML-KEM keypair to generate an agreed secret
2831
// and a ciphertext. Only a peer with the private information of a Composite ML-KEM keypair can
2832
// decapsulate the ciphertext to compute the agreed secret.
2833
//
2834
// The arguments are the following:
2835
// - pkCompositeMlKemkey: a key which contains public information required for encapsulation.
2836
// - (pbMlKemRandom, cbMlKemRandom): a buffer containing the input random for the ML-KEM component.
2837
// When pbMlKemRandom is NULL, cbMlKemRandom should be 0, and the function will generate the necessary random input internally.
2838
// Currently when pbMlKemRandom is not NULL, cbMlKemRandom must be 32 for all parameterizations of Composite ML-KEM.
2839
// - (pbTradRandom, cbTradRandom): a buffer containing the input random for the traditional component.
2840
// When the traditional portion is an EC key, cbTradRandom must be equal to the private key size of the EC key.
2841
// If pbTradRandom is NULL, cbTradRandom should be 0, and the function will generate the necessary random input internally.
2842
// Currently, only EC keys are supported for the traditional component.
2843
// - (pbAgreedSecret, cbAgreedSecret): a buffer into which the generated secret is written.
2844
// Currently cbAgreedSecret must be 32 for all parameterizations of Composite ML-KEM.
2845
// - (pbCiphertext, cbCiphertext): a buffer into which the encapsulated secret is written.
2846
// cbCiphertext must equal cbCiphertext given by SymCryptCompositeMlKemSizeofCiphertextFromParams,
2847
// though typically this value can be known statically (see definition of
2848
// SYMCRYPT_COMPOSITE_MLKEM_CIPHERTEXT_SIZE_*).
2849
//
2850
2851
//===================================================================
2852
// 802.11 SAE protocol
2853
//===================================================================
2854
//
2855
// WARNING: These functions are NOT part of the stable SymCrypt API. They are a private
2856
// interface for the Windows WiFi driver. These functions can change or disappear
2857
// at any time as we update our WiFi solutions.
2858
//
2859
// These functions implement the non-standard or 'custom' parts of the SAE protocol for
2860
// 802.11 SAE as specified in IEEE 801.11-2016 12.4
2861
//
2862
// Parts of the protocol that are easy to implement with conventional crypto functions are
2863
// not included in this custom part.
2864
//
2865
// Limitation: The Hunting-and-Pecking method supports only NIST P256 curve. The Hash-to-Element
2866
// method supports curves NIST P256 and NIST P384.
2867
//
2868
2869
//
2870
// IANA Group numbers identify the elliptic curve and associated parameters to be used in the SAE method.
2871
//
2872
typedef enum _SYMCRYPT_802_11_SAE_GROUP {
2873
SYMCRYPT_SAE_GROUP_19 = 19, // NIST P256
2874
SYMCRYPT_SAE_GROUP_20, // NIST P384
2875
} SYMCRYPT_802_11_SAE_GROUP;
2876
2877
// The sizes of scalars, elliptic curve points, and HMAC outputs will vary depending on which group is selected.
2878
// The following macros define the largest possible sizes supported.
2879
#define SYMCRYPT_SAE_MAX_MOD_SIZE_BITS 384
2880
#define SYMCRYPT_SAE_MAX_MOD_SIZE_BYTES SYMCRYPT_BYTES_FROM_BITS( SYMCRYPT_SAE_MAX_MOD_SIZE_BITS )
2881
#define SYMCRYPT_SAE_MAX_EC_POINT_SIZE_BYTES ( 2 * SYMCRYPT_SAE_MAX_MOD_SIZE_BYTES )
2882
#define SYMCRYPT_SAE_MAX_HMAC_OUTPUT_SIZE_BYTES SYMCRYPT_BYTES_FROM_BITS( 384 )
2883
2884
2885
typedef struct _SYMCRYPT_802_11_SAE_CUSTOM_STATE SYMCRYPT_802_11_SAE_CUSTOM_STATE, *PSYMCRYPT_802_11_SAE_CUSTOM_STATE;
2886
typedef const SYMCRYPT_802_11_SAE_CUSTOM_STATE *PCSYMCRYPT_802_11_SAE_CUSTOM_STATE;
2887
//
2888
// The struct itself is opaque and is defined elsewhere.
2889
// Caller may not rely on the internal fields of the structure as they can
2890
// change at any time.
2891
//
2892
2893
VOID SymCrypt802_11SaeGetGroupSizes(
2894
SYMCRYPT_802_11_SAE_GROUP group,
2895
_Out_opt_ SIZE_T* pcbScalar,
2896
_Out_opt_ SIZE_T* pcbPoint );
2897
//
2898
// Helper function that returns the sizes of the field elements and elliptic curve points in bytes
2899
// for a given IANA group number. Both output parameters are optional.
2900
//
2901
2902
SYMCRYPT_ERROR
2903
SymCrypt802_11SaeCustomInit(
2904
_Out_ PSYMCRYPT_802_11_SAE_CUSTOM_STATE pState,
2905
_In_reads_( 6 ) PCBYTE pbMacA,
2906
_In_reads_( 6 ) PCBYTE pbMacB,
2907
_In_reads_( cbPassword ) PCBYTE pbPassword,
2908
SIZE_T cbPassword,
2909
_Out_opt_ PBYTE pbCounter,
2910
_Inout_updates_opt_( 32 ) PBYTE pbRand,
2911
_Inout_updates_opt_( 32 ) PBYTE pbMask );
2912
//
2913
// Initialize the state object with the MAC addresses and password.
2914
// All choices for the protocol (i.e. rand and mask) are made at this time.
2915
//
2916
// - State Protocol state to initialize
2917
// - pbMacA, pbMacB Two 6-byte MAC addresses with MacA >= MacB.
2918
// - pbPassword, cbPassword The password buffer
2919
// - pbCounter If not NULL, receives the counter value of the
2920
// successful PWE generation per section 12.4.4.2.2
2921
// - pbRand Optional pointer to Rand buffer (see below)
2922
// - pbMask Optional pointer to Mask buffer (see below)
2923
//
2924
// The Rand and Mask buffers are optional. If a pointer is not provided then the caller
2925
// has no access to the corresponding value.
2926
// For either of these pointers there are three cases:
2927
// - If a NULL pointer is provided, the function generates an appropriate value internally,
2928
// but does not return it to the caller.
2929
// - If a buffer is provided and the buffer is all-zero, the function generates an appropriate
2930
// value internally and returns it in the buffer.
2931
// - If a buffer is provided and the buffer is nonzero, the value in the buffer is used for
2932
// the corresponding protocol parameter without further validation.
2933
// This last option is useful for testing as it lets the caller specify all the random choices.
2934
// Rand and Mask buffers are MSByte first.
2935
//
2936
// Note: currently this method only supports the NIST P256 curve. If we ever want to support other curves
2937
// we'll update this function to accept a curve parameter and update the SAL annotations
2938
// of the other functions.
2939
//
2940
2941
SYMCRYPT_ERROR
2942
SymCrypt802_11SaeCustomCreatePT(
2943
_In_reads_( cbSsid ) PCBYTE pbSsid,
2944
SIZE_T cbSsid,
2945
_In_reads_( cbPassword ) PCBYTE pbPassword,
2946
SIZE_T cbPassword,
2947
_In_reads_opt_( cbPasswordIdentifier ) PCBYTE pbPasswordIdentifier,
2948
SIZE_T cbPasswordIdentifier,
2949
_Out_writes_( 64 ) PBYTE pbPT );
2950
//
2951
// Generate the PT secret element for use with the SAE Hash-to-Element algorithm, as described in
2952
// section 12.4.4.2.3 of the 802.11 spec ("Hash-to-curve generation of the password element with
2953
// ECC groups"). The PT value can be "stored until needed to generate a session specific PWE."
2954
//
2955
// - pbSsid, cbSsid SSID for the connection as a string of bytes
2956
// - pbPassword, cbPassword Password buffer
2957
// - pbPasswordIdentifier, cbPasswordIdentifier Optional password identifier, as a string of bytes
2958
// - pbPT Out pointer to PT (as a byte buffer)
2959
//
2960
// This function uses the NIST P256 curve.
2961
//
2962
2963
2964
SYMCRYPT_ERROR
2965
SymCrypt802_11SaeCustomCreatePTGeneric(
2966
SYMCRYPT_802_11_SAE_GROUP group,
2967
_In_reads_( cbSsid ) PCBYTE pbSsid,
2968
SIZE_T cbSsid,
2969
_In_reads_( cbPassword ) PCBYTE pbPassword,
2970
SIZE_T cbPassword,
2971
_In_reads_opt_( cbPasswordIdentifier ) PCBYTE pbPasswordIdentifier,
2972
SIZE_T cbPasswordIdentifier,
2973
_Out_writes_( cbPT ) PBYTE pbPT,
2974
SIZE_T cbPT );
2975
//
2976
// Generic version of the SymCrypt802_11SaeCustomCreatePT() function that allows elliptic curve
2977
// group selection.
2978
// Generate the PT secret element for use with the SAE Hash-to-Element algorithm, as described in
2979
// section 12.4.4.2.3 of the 802.11 spec ("Hash-to-curve generation of the password element with
2980
// ECC groups"). The PT value can be "stored until needed to generate a session specific PWE."
2981
//
2982
// - group Group number for the elliptic curve selection
2983
// - pbSsid, cbSsid SSID for the connection as a string of bytes
2984
// - pbPassword, cbPassword Password buffer
2985
// - pbPasswordIdentifier, cbPasswordIdentifier Optional password identifier, as a string of bytes
2986
// - pbPT, cbPt PT (as a byte buffer)
2987
//
2988
2989
2990
SYMCRYPT_ERROR
2991
SymCrypt802_11SaeCustomInitH2E(
2992
_Out_ PSYMCRYPT_802_11_SAE_CUSTOM_STATE pState,
2993
_In_reads_( 64 ) PCBYTE pbPT,
2994
_In_reads_( 6 ) PCBYTE pbMacA,
2995
_In_reads_( 6 ) PCBYTE pbMacB,
2996
_Inout_updates_opt_( 32 ) PBYTE pbRand,
2997
_Inout_updates_opt_( 32 ) PBYTE pbMask );
2998
//
2999
// Initialize the state object using the Hash-to-Element algorithm, using the PT value calculated
3000
// by SymCrypt802_11SaeCustomCreatePT.
3001
//
3002
// - pState Protocol state
3003
// - pbPT PT value calculated using SymCrypt802_11SaeCustomCreatePT()
3004
// - pbMacA, pbMacB Two 6-byte MAC addresses
3005
// - pbRand Optional pointer to Rand buffer. See SymCrypt802_11SaeCustomInit() documentation for the use of this parameter.
3006
// - pbMask Optional pointer to Mask buffer. See SymCrypt802_11SaeCustomInit() documentation for the use of this parameter.
3007
//
3008
// See the comment on SymCrypt802_11SaeCustomInit() for more details about the pbRand and pbMask
3009
// parameters.
3010
//
3011
3012
3013
SYMCRYPT_ERROR
3014
SymCrypt802_11SaeCustomInitH2EGeneric(
3015
_Out_ PSYMCRYPT_802_11_SAE_CUSTOM_STATE pState,
3016
SYMCRYPT_802_11_SAE_GROUP group,
3017
_In_reads_( cbPT ) PCBYTE pbPT,
3018
SIZE_T cbPT,
3019
_In_reads_( 6 ) PCBYTE pbMacA,
3020
_In_reads_( 6 ) PCBYTE pbMacB,
3021
_Inout_updates_opt_( cbRand ) PBYTE pbRand,
3022
SIZE_T cbRand,
3023
_Inout_updates_opt_( cbMask ) PBYTE pbMask,
3024
SIZE_T cbMask );
3025
//
3026
// Generic version of the SymCrypt802_11SaeCustomInitH2E() function that allows elliptic curve
3027
// group selection.
3028
// Initialize the state object using the Hash-to-Element algorithm, using the PT value calculated
3029
// by SymCrypt802_11SaeCustomCreatePT.
3030
//
3031
// - pState Protocol state
3032
// - group Group number for the elliptic curve selection
3033
// - pbPT, cbPT PT value (as a byte array) calculated using SymCrypt802_11SaeCustomCreatePTGeneric().
3034
// PT must be generated on the same elliptic curve as the one supplied in the group parameter.
3035
// - pbMacA, pbMacB Two 6-byte MAC addresses
3036
// - pbRand, cbRand Optional Rand buffer. See SymCrypt802_11SaeCustomInit() documentation for the use of this parameter.
3037
// - pbMask, cbMask Optional Mask buffer. See SymCrypt802_11SaeCustomInit() documentation for the use of this parameter.
3038
//
3039
// See the comment on SymCrypt802_11SaeCustomInit() for more details about the pbRand and pbMask
3040
// parameters.
3041
//
3042
3043
SYMCRYPT_ERROR
3044
SymCrypt802_11SaeCustomCommitCreate(
3045
_In_ PCSYMCRYPT_802_11_SAE_CUSTOM_STATE pState,
3046
_Out_writes_( 32 ) PBYTE pbCommitScalar,
3047
_Out_writes_( 64 ) PBYTE pbCommitElement );
3048
//
3049
// Compute the commit-scalar and commit-element values for the Commit message.
3050
// This function does not update the pState and is multi-thread safe w.r.t. the pState object.
3051
//
3052
// - pState Protocol state that was initialized with SymCrypt802_11SaeCustomInit().
3053
// - pCommitScalar Buffer that receives the commit-scalar value, MSByte first.
3054
// - pCommitElement Buffer that receives the commit-element value encoded as two values
3055
// (x,y) in order, each value in MSByte first.
3056
//
3057
3058
SYMCRYPT_ERROR
3059
SymCrypt802_11SaeCustomCommitCreateGeneric(
3060
_In_ PCSYMCRYPT_802_11_SAE_CUSTOM_STATE pState,
3061
_Out_writes_( cbCommitScalar ) PBYTE pbCommitScalar,
3062
SIZE_T cbCommitScalar,
3063
_Out_writes_( cbCommitElement ) PBYTE pbCommitElement,
3064
SIZE_T cbCommitElement);
3065
//
3066
// Generic version of the SymCrypt802_11SaeCustomCommitCreate() function that uses the
3067
// state object to determine which elliptic curve group is selected.
3068
// Compute the commit-scalar and commit-element values for the Commit message.
3069
// This function does not update the pState and is multi-thread safe w.r.t. the pState object.
3070
//
3071
// - pState Protocol state that was initialized with SymCrypt802_11SaeCustomInit().
3072
// - pbCommitScalar, cbCommitScalar Buffer that receives the commit-scalar value, MSByte first.
3073
// - pbCommitElement, cbCommitElement Buffer that receives the commit-element value encoded as two values
3074
// (x,y) in order, each value in MSByte first.
3075
//
3076
3077
SYMCRYPT_ERROR
3078
SymCrypt802_11SaeCustomCommitProcess(
3079
_In_ PCSYMCRYPT_802_11_SAE_CUSTOM_STATE pState,
3080
_In_reads_( 32 ) PCBYTE pbPeerCommitScalar,
3081
_In_reads_( 64 ) PCBYTE pbPeerCommitElement,
3082
_Out_writes_( 32 ) PBYTE pbSharedSecret,
3083
_Out_writes_( 32 ) PBYTE pbScalarSum );
3084
//
3085
// Process the commit message received from the peer.
3086
// This function does not update pState and is multi-thread safe w.r.t. the pState object.
3087
//
3088
// - pState pointer to the protocol state.
3089
// - pbPeerCommitScalar pointer to the peer's commit scalar value, MSByte first.
3090
// - pbPeerCommitElement pointer to the peer's commit element, see CommitCreate for format.
3091
// - pbSharedSecret buffer that receives the 'k' value that is the shared secret, MSByte first
3092
// - pbScalarSum buffer that receives the sum of the two commit scalars, MSByte first
3093
//
3094
3095
SYMCRYPT_ERROR
3096
SymCrypt802_11SaeCustomCommitProcessGeneric(
3097
_In_ PCSYMCRYPT_802_11_SAE_CUSTOM_STATE pState,
3098
_In_reads_( cbPeerCommitScalar ) PCBYTE pbPeerCommitScalar,
3099
SIZE_T cbPeerCommitScalar,
3100
_In_reads_( cbPeerCommitElement ) PCBYTE pbPeerCommitElement,
3101
SIZE_T cbPeerCommitElement,
3102
_Out_writes_( cbSharedSecret ) PBYTE pbSharedSecret,
3103
SIZE_T cbSharedSecret,
3104
_Out_writes_( cbScalarSum ) PBYTE pbScalarSum,
3105
SIZE_T cbScalarSum );
3106
//
3107
// Generic version of the SymCrypt802_11SaeCustomCommitProcess() function that uses the
3108
// state object to determine which elliptic curve group is selected.
3109
// Process the commit message received from the peer.
3110
// This function does not update pState and is multi-thread safe w.r.t. the pState object.
3111
//
3112
// - pState pointer to the protocol state.
3113
// - pbPeerCommitScalar, cbPeerCommitScalar pointer to the peer's commit scalar value, MSByte first.
3114
// - pbPeerCommitElement, cbPeerCommitElement pointer to the peer's commit element, see CommitCreate for format.
3115
// - pbSharedSecret, cbSharedSecret buffer that receives the 'k' value that is the shared secret, MSByte first
3116
// - pbScalarSum, pbSharedSecret buffer that receives the sum of the two commit scalars, MSByte first
3117
//
3118
3119
3120
VOID
3121
SymCrypt802_11SaeCustomDestroy(
3122
_Inout_ PSYMCRYPT_802_11_SAE_CUSTOM_STATE pState );
3123
//
3124
// Wipe a state object.
3125
// After this call the memory used for pState is uninitialized and can be used for other purposes.
3126
// Note that it is not safe to just wipe the memory of the state object as the state
3127
// object contains pointers to other allocations, which can contain secret information.
3128
// The only way to safely destroy a state is to use this function.
3129
//
3130
3131
//===================================================================
3132
3133
3134
3135
#ifdef __cplusplus
3136
}
3137
#endif
3138
3139