Coverage Report

Created: 2024-11-21 07:03

/src/SymCrypt/inc/symcrypt_internal.h
Line
Count
Source (jump to first uncovered line)
1
//
2
// SymCrypt_internal.h
3
//
4
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
5
//
6
7
//
8
// This file contains information that is internal to the symcrypt library,
9
// but which still needs to be known to the compiler to be able to use the library.
10
// This includes structure declarations and all support for inline implementations
11
// of some of the library functions.
12
// Information in this file is not part of the API and can change at any time.
13
//
14
15
//
16
// We use Prefast pragmas, but they are not recognized by the compiler.
17
// We disable the 'unknown pragma' warning if we are not in prefast mode.
18
//
19
#ifndef _PREFAST_
20
#pragma warning(disable:4068)
21
#endif
22
23
//==============================================================================================
24
//  PLATFORM/COMPILER DETECTION
25
//==============================================================================================
26
27
#define SYMCRYPT_PLATFORM_WINDOWS 0
28
#define SYMCRYPT_PLATFORM_APPLE   0 // MacOS and other Apple platforms
29
#define SYMCRYPT_PLATFORM_UNIX    0 // Linux and other Unix-likes, besides MacOS. Must support POSIX.
30
31
#if defined(_WIN32)
32
    #undef  SYMCRYPT_PLATFORM_WINDOWS
33
    #define SYMCRYPT_PLATFORM_WINDOWS 1
34
#elif defined(__APPLE__)
35
    #undef  SYMCRYPT_PLATFORM_APPLE
36
    #define SYMCRYPT_PLATFORM_APPLE 1
37
#elif (defined(linux) || defined(__unix__))
38
    #undef  SYMCRYPT_PLATFORM_UNIX
39
    #define SYMCRYPT_PLATFORM_UNIX 1
40
#endif
41
42
#define SYMCRYPT_MS_VC       0 // Microsoft compiler (cl.exe - Visual Studio/MSBuild)
43
#define SYMCRYPT_GNUC        0 // GCC and compatible compilers (including Clang)
44
45
#if defined(_MSC_VER)
46
    #undef  SYMCRYPT_MS_VC
47
    #define SYMCRYPT_MS_VC  1
48
#elif defined(__GNUC__)
49
    #undef  SYMCRYPT_GNUC
50
    #define SYMCRYPT_GNUC 1
51
#else
52
    #error Unsupported compiler
53
#endif
54
55
#if SYMCRYPT_MS_VC
56
57
// This should go somewhere else. Same in the other #if branches.
58
#define SYMCRYPT_ANYSIZE_ARRAY               1
59
#define SYMCRYPT_NOINLINE __declspec(noinline)
60
#define SYMCRYPT_CDECL __cdecl
61
#define SYMCRYPT_FASTCALL __fastcall
62
63
#define SYMCRYPT_UNALIGNED
64
65
#elif SYMCRYPT_GNUC
66
67
// Suppress the SAL annotations
68
#include "symcrypt_no_sal.h"
69
70
// Ignore the multi-character character constant warnings
71
#pragma GCC diagnostic ignored "-Wmultichar"
72
73
0
#define C_ASSERT(e)                 typedef char __C_ASSERT__[(e)?1:-1]
74
#define SYMCRYPT_ANYSIZE_ARRAY               1
75
#define FORCEINLINE                 static inline //__inline__ __attribute__ ((always_inline))
76
#define SYMCRYPT_NOINLINE           __attribute__ ((noinline))
77
#define SYMCRYPT_UNALIGNED
78
#define SYMCRYPT_CDECL
79
#define SYMCRYPT_FASTCALL           __attribute__((fastcall))
80
81
#endif
82
83
//==============================================================================================
84
//  PLATFORM SPECIFICS
85
//==============================================================================================
86
87
//
88
// SYMCRYPT_CALL & SYMCRYPT_ALIGN
89
//
90
// SYMCRYPT_CALL is a macro that selects the calling convention used by the library.
91
// Crypto functions often have to perform very many small operations, and a fast calling convention is
92
// preferable. We use __fastcall on platforms that support it.
93
//
94
// SYMCRYPT_ALIGN is the default alignment for the platform.
95
// On platforms that have alignment restrictions the default alignment should be large enough that
96
// an aligned BYTE * can be cast to a pointer to a UINT32 and be used.
97
//
98
//
99
// The SYMCRYPT_IGNORE_PLATFORM macro can be defined to switch off any platform-specific
100
// optimizations and run just the C implementations.
101
// The rest of the library uses SYMCRYPT_CPU_* macros to make platform decisions.
102
//
103
//
104
// WARNING: both the library and the calling application must be compiled with the same
105
// set of flags, as the flags affect things like the structure layout and size and
106
// the calling convention, both of which need to be in sync between the lib and the caller.
107
//
108
109
//#define SYMCRYPT_IGNORE_PLATFORM        // #defining this flag disables all platform optimizations.
110
111
#define SYMCRYPT_CPU_X86            0
112
#define SYMCRYPT_CPU_AMD64          0
113
#define SYMCRYPT_CPU_ARM            0
114
#define SYMCRYPT_CPU_ARM64          0
115
#define SYMCRYPT_CPU_UNKNOWN        0
116
117
#if (defined( _X86_ ) || defined( _M_IX86 ) || defined( __i386__ )) && !defined ( SYMCRYPT_IGNORE_PLATFORM )
118
119
#undef  SYMCRYPT_CPU_X86
120
#define SYMCRYPT_CPU_X86        1
121
122
#define SYMCRYPT_CALL           SYMCRYPT_FASTCALL
123
#define SYMCRYPT_ALIGN_VALUE    4
124
125
#ifndef _PREFAST_
126
#pragma warning(push)
127
#pragma warning(disable:4359)   // *** Alignment specifier is less than actual alignment
128
#endif
129
130
#elif (defined( _ARM64_ ) || defined( _ARM64EC_ ) || defined( _M_ARM64 ) || defined( __aarch64__ )) && !defined( SYMCRYPT_IGNORE_PLATFORM )
131
132
#undef  SYMCRYPT_CPU_ARM64
133
#define SYMCRYPT_CPU_ARM64      1
134
#define SYMCRYPT_CALL
135
#define SYMCRYPT_ALIGN_VALUE    16
136
137
#elif (defined( _AMD64_ ) || defined( _M_AMD64 ) || defined( __amd64__ )) && !defined ( SYMCRYPT_IGNORE_PLATFORM )
138
139
#undef  SYMCRYPT_CPU_AMD64
140
0
#define SYMCRYPT_CPU_AMD64      1
141
142
#define SYMCRYPT_CALL
143
#define SYMCRYPT_ALIGN_VALUE    16
144
145
#elif (defined( _ARM_ ) || defined( _M_ARM ) || defined( __arm__ )) && !defined( SYMCRYPT_IGNORE_PLATFORM )
146
147
#undef  SYMCRYPT_CPU_ARM
148
#define SYMCRYPT_CPU_ARM        1
149
#define SYMCRYPT_CALL
150
#define SYMCRYPT_ALIGN_VALUE    8
151
152
#elif defined( SYMCRYPT_IGNORE_PLATFORM )
153
154
#undef  SYMCRYPT_CPU_UNKNOWN
155
#define SYMCRYPT_CPU_UNKNOWN    1
156
#define SYMCRYPT_CALL
157
#define SYMCRYPT_ALIGN_VALUE    16
158
159
#ifndef _PREFAST_
160
#pragma warning(push)
161
#pragma warning(disable:4359)   // *** Alignment specifier is less than actual alignment
162
#endif
163
164
#else
165
166
#error Unknown CPU platform
167
168
#endif   // SYMCRYPT_CALL platforms switch
169
170
171
//
172
// Datatypes used by the SymCrypt library. This ensures compatibility
173
// with multiple environments, such as Windows, iOS, and Android.
174
//
175
176
#if SYMCRYPT_MS_VC
177
178
    //
179
    // Types included in intsafe.h:
180
    //      BYTE,
181
    //      INT16, UINT16,
182
    //      INT32, UINT32,
183
    //      INT64, UINT64,
184
    //      UINT_PTR
185
    // and macro:
186
    //      UINT32_MAX
187
    //
188
#include <intsafe.h>
189
190
#else
191
192
#include <stdint.h>
193
194
typedef uint8_t         BYTE;
195
196
#ifndef UINT32_MAX
197
#define UINT32_MAX      (0xffffffff)
198
#endif
199
200
#ifndef TRUE
201
3.18M
#define TRUE            0x01
202
#endif
203
204
#ifndef FALSE
205
3.21M
#define FALSE           0x00
206
#endif
207
208
// Size_t
209
typedef size_t          SIZE_T;
210
211
#ifndef SIZE_T_MAX
212
#define SIZE_T_MAX      SIZE_MAX
213
#endif
214
215
typedef long INT_PTR, *PINT_PTR;
216
typedef unsigned long UINT_PTR, *PUINT_PTR;
217
218
typedef long LONG_PTR, *PLONG_PTR;
219
typedef unsigned long ULONG_PTR, *PULONG_PTR;
220
221
typedef int                 BOOL;
222
typedef unsigned int        UINT;
223
typedef unsigned long       ULONG;
224
225
typedef int8_t              INT8, *PINT8;
226
typedef int16_t             INT16, *PINT16;
227
typedef int32_t             INT32, *PINT32;
228
typedef int64_t             INT64, *PINT64;
229
typedef uint8_t             UINT8, *PUINT8;
230
typedef uint16_t            UINT16, *PUINT16;
231
typedef uint32_t            UINT32, *PUINT32;
232
typedef uint64_t            UINT64, *PUINT64;
233
234
typedef uint32_t            ULONG32, *PULONG32;
235
236
// minwindef.h
237
typedef char CHAR;
238
239
#endif //WIN32
240
241
#include <stddef.h>
242
243
//
244
// Pointer types
245
//
246
typedef BYTE *          PBYTE;
247
typedef const BYTE *    PCBYTE;
248
249
typedef UINT16 *        PUINT16;
250
typedef const UINT16 *  PCUINT16;
251
252
typedef UINT32 *        PUINT32;
253
typedef const UINT32 *  PCUINT32;
254
255
typedef UINT64 *        PUINT64;
256
typedef const UINT64 *  PCUINT64;
257
258
// Void
259
260
#ifndef VOID
261
#define VOID void
262
#endif
263
264
typedef void *          PVOID;
265
typedef const void *    PCVOID;
266
267
// winnt.h
268
typedef BYTE  BOOLEAN;
269
270
// Useful macros for structs
271
46.7k
#define SYMCRYPT_FIELD_OFFSET(type, field)      (offsetof(type, field))
272
#define SYMCRYPT_FIELD_SIZE(type, field)        (sizeof( ((type *)0)->field ))
273
274
#if SYMCRYPT_MS_VC
275
276
#ifndef FORCEINLINE
277
#if (_MSC_VER >= 1200)
278
#define FORCEINLINE __forceinline
279
#else
280
#define FORCEINLINE __inline
281
#endif
282
#endif
283
284
#else
285
286
#define FORCEINLINE static inline
287
288
#endif
289
290
C_ASSERT( (SYMCRYPT_ALIGN_VALUE & (SYMCRYPT_ALIGN_VALUE - 1 )) == 0 );
291
#define SYMCRYPT_ALIGN_UP( _p ) ((PBYTE) ( ((UINT_PTR) (_p) + SYMCRYPT_ALIGN_VALUE - 1) & ~(SYMCRYPT_ALIGN_VALUE - 1 ) ) )
292
293
#if SYMCRYPT_MS_VC
294
    #define SYMCRYPT_ALIGN_AT(alignment)                 __declspec(align(alignment))
295
    #define SYMCRYPT_ALIGN_TYPE_AT(typename, alignment)  typename SYMCRYPT_ALIGN_AT(alignment)
296
    #define SYMCRYPT_WEAK_SYMBOL
297
#elif SYMCRYPT_GNUC
298
149k
    #define SYMCRYPT_ALIGN_AT(alignment)                 __attribute__((aligned(alignment)))
299
    #define SYMCRYPT_ALIGN_TYPE_AT(typename, alignment)  typename SYMCRYPT_ALIGN_AT(alignment)
300
    #define SYMCRYPT_WEAK_SYMBOL                         __attribute__((weak))
301
#else
302
    #define SYMCRYPT_ALIGN_AT(alignment)
303
    #define SYMCRYPT_ALIGN_TYPE_AT(typename, alignment)  typename
304
    #define SYMCRYPT_WEAK_SYMBOL
305
#endif
306
149k
#define SYMCRYPT_ALIGN          SYMCRYPT_ALIGN_AT(SYMCRYPT_ALIGN_VALUE)
307
#define SYMCRYPT_ALIGN_STRUCT   SYMCRYPT_ALIGN_TYPE_AT(struct, SYMCRYPT_ALIGN_VALUE)
308
#define SYMCRYPT_ALIGN_UNION    SYMCRYPT_ALIGN_TYPE_AT(union, SYMCRYPT_ALIGN_VALUE)
309
310
311
11.3k
#define SYMCRYPT_MAX( _a, _b )  ((_a)>(_b)?(_a):(_b))
312
572k
#define SYMCRYPT_MIN( _a, _b )  ((_a)<(_b)?(_a):(_b))
313
314
#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64
315
//
316
// XMM related declarations, used in data structures.
317
//
318
#pragma prefast(push)
319
#pragma prefast(disable: 28251, "Windows headers define _mm_clflush with SAL annotation, Intel header doesn't have SAL annotation leading to inconsistent annotation errors")
320
#include <emmintrin.h>
321
#pragma prefast(pop)
322
#endif
323
324
325
//
326
// To provide quick error detection we have magic values in all
327
// our data structures, but only in CHKed builds.
328
// Our magic value depends on the address of the structure.
329
// This has the advantage that we detect blind memcpy's of our data structures.
330
// Memcpy is not supported as it limits what the library is allowed to do.
331
// Where needed the library provides for copy functions of its internal data structures.
332
//
333
#if SYMCRYPT_DEBUG
334
    #define SYMCRYPT_MAGIC_ENABLED
335
#endif
336
337
#if defined(SYMCRYPT_MAGIC_ENABLED )
338
339
#define SYMCRYPT_MAGIC_FIELD        SIZE_T   magic;
340
1.40M
#define SYMCRYPT_MAGIC_VALUE( p )   ((SIZE_T) p + 'S1mv' + SYMCRYPT_API_VERSION)
341
342
343
233k
#define SYMCRYPT_SET_MAGIC( p )     {(p)->magic = SYMCRYPT_MAGIC_VALUE( p );}
344
1.16M
#define SYMCRYPT_CHECK_MAGIC( p )   {if((p)->magic!=SYMCRYPT_MAGIC_VALUE(p)) SymCryptFatal('magc');}
345
#define SYMCRYPT_WIPE_MAGIC( p )    {(p)->magic = 0;}
346
347
#else
348
349
//
350
// We define the magic field even for FRE builds, because we get too many
351
// hard-to-debug problems with people who accidentally mix FRE headers with CHKed libraries,
352
// or the other way around.
353
// E.g. BitLocker only publishes the FRE version of their library, and building a CHKed binary with
354
// that FRE lib crashes
355
//
356
357
#define SYMCRYPT_MAGIC_FIELD        SIZE_T   magic;
358
#define SYMCRYPT_SET_MAGIC( p )
359
#define SYMCRYPT_CHECK_MAGIC( p )
360
#define SYMCRYPT_WIPE_MAGIC( p )
361
362
#endif
363
364
//
365
// CPU feature detection infrastructure
366
//
367
368
#if SYMCRYPT_GNUC
369
    // Forward declarations for CPUID intrinsic replacements
370
    void __cpuidex(int CPUInfo[4], int InfoType, int ECXValue);
371
#endif
372
373
#if SYMCRYPT_CPU_ARM || SYMCRYPT_CPU_ARM64
374
375
#define SYMCRYPT_CPU_FEATURE_NEON           0x01
376
#define SYMCRYPT_CPU_FEATURE_NEON_AES       0x02
377
#define SYMCRYPT_CPU_FEATURE_NEON_PMULL     0x04
378
#define SYMCRYPT_CPU_FEATURE_NEON_SHA256    0x08
379
380
#elif SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64
381
382
//
383
// We keep the most commonly tested bits in the least significant byte, to make it easier for the compiler to optimize
384
// There is a many to one relationship between CPUID feature flags and SYMCRYPT_CPU_FEATURE_XXX bits
385
// since a SYMCRYPT_CPU_FEATURE_XXX could require multiple CPUID features.
386
387
#define SYMCRYPT_CPU_FEATURE_SSE2               0x0001          // includes SSE, SSE2
388
#define SYMCRYPT_CPU_FEATURE_SSSE3              0x0002          // includes SSE, SSE2, SSE3, SSSE3
389
#define SYMCRYPT_CPU_FEATURE_AESNI              0x0004
390
#define SYMCRYPT_CPU_FEATURE_PCLMULQDQ          0x0008
391
#define SYMCRYPT_CPU_FEATURE_AVX2               0x0010          // includes AVX, AVX2 - also indicates support for saving/restoring Ymm registers
392
#define SYMCRYPT_CPU_FEATURE_SAVEXMM_NOFAIL     0x0020          // if SymCryptSaveXmm() will never fail
393
#define SYMCRYPT_CPU_FEATURE_SHANI              0x0040
394
#define SYMCRYPT_CPU_FEATURE_BMI2               0x0080          // MULX, RORX, SARX, SHLX, SHRX
395
396
#define SYMCRYPT_CPU_FEATURE_ADX                0x0100          // ADCX, ADOX
397
#define SYMCRYPT_CPU_FEATURE_RDRAND             0x0200
398
#define SYMCRYPT_CPU_FEATURE_RDSEED             0x0400
399
#define SYMCRYPT_CPU_FEATURE_VAES               0x0800          // support for VAES and VPCLMULQDQ (may only be supported on Ymm registers (i.e. Zen3))
400
#define SYMCRYPT_CPU_FEATURE_AVX512             0x1000          // includes F, VL, DQ, BW (VL allows AVX-512 instructions to be used on Xmm and Ymm registers)
401
                                                                // also indicates support for saving/restoring additional AVX-512 state
402
403
#define SYMCRYPT_CPU_FEATURE_CMPXCHG16B         0x2000          // Compare and Swap 128b value
404
405
#endif
406
407
typedef UINT32 SYMCRYPT_CPU_FEATURES;
408
409
//
410
// We have two feature fields.
411
// g_SymCryptCpuFeaturesNotPresent reports with features are not present on the current CPU
412
// SymCryptCpuFeaturesNeverPresent() is a function that returns a static (compiler-predictable) value,
413
//  and allows the environment to lock out features in a way that the compiler can optimize away all the code that uses these features.
414
// Using a function allows the environment macro to forward it to an environment-specific function.
415
//
416
417
extern SYMCRYPT_CPU_FEATURES g_SymCryptCpuFeaturesNotPresent;
418
419
SYMCRYPT_CPU_FEATURES
420
SYMCRYPT_CALL
421
SymCryptCpuFeaturesNeverPresent(void);
422
423
1.36M
#define SYMCRYPT_CPU_FEATURES_PRESENT( x )   ( ((x) & SymCryptCpuFeaturesNeverPresent()) == 0 && ( (x) & g_SymCryptCpuFeaturesNotPresent ) == 0 )
424
425
//
426
// VOLATILE MEMORY ACCESS
427
//
428
// These macros are used to explicitly handle volatile memory access independent of compiler settings.
429
// If volatile memory is accessed directly without using the appropriate macro, MSVC may emit warning
430
// C4746, because the volatile semantics depend on the value of the /volatile flag, which can result in
431
// undesired hardware memory barriers that impact performance.
432
//
433
// More info:
434
// https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-c4746?view=msvc-170
435
// https://docs.microsoft.com/en-us/cpp/build/reference/volatile-volatile-keyword-interpretation?view=msvc-170
436
//
437
438
#if SYMCRYPT_MS_VC  // Microsoft VC++ Compiler
439
440
    #if SYMCRYPT_CPU_ARM || SYMCRYPT_CPU_ARM64
441
        #define SYMCRYPT_INTERNAL_VOLATILE_READ8( _p )    ( __iso_volatile_load8( (const volatile char*)(_p) ) )
442
        #define SYMCRYPT_INTERNAL_VOLATILE_READ16( _p )   ( __iso_volatile_load16( (const volatile short*)(_p) ) )
443
        #define SYMCRYPT_INTERNAL_VOLATILE_READ32( _p )   ( __iso_volatile_load32( (const volatile int*)(_p) ) )
444
        #define SYMCRYPT_INTERNAL_VOLATILE_READ64( _p )   ( __iso_volatile_load64( (const volatile __int64*)(_p) ) )
445
446
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v )  ( __iso_volatile_store8( (volatile char*)(_p), (_v) ) )
447
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v ) ( __iso_volatile_store16( (volatile short*)(_p), (_v) ) )
448
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v ) ( __iso_volatile_store32( (volatile int*)(_p), (_v) ) )
449
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE64( _p, _v ) ( __iso_volatile_store64( (volatile __int64*)(_p), (_v) ) )
450
    #elif SYMCRYPT_CPU_X86 || SYMCRYPT_CPU_AMD64
451
        #define SYMCRYPT_INTERNAL_VOLATILE_READ8( _p )    ( *((const volatile BYTE*)  (_p)) )
452
        #define SYMCRYPT_INTERNAL_VOLATILE_READ16( _p )   ( *((const volatile UINT16*)(_p)) )
453
        #define SYMCRYPT_INTERNAL_VOLATILE_READ32( _p )   ( *((const volatile UINT32*)(_p)) )
454
        #define SYMCRYPT_INTERNAL_VOLATILE_READ64( _p )   ( *((const volatile UINT64*)(_p)) )
455
456
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v )  ( *((volatile BYTE*)  (_p)) = (_v) )
457
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v ) ( *((volatile UINT16*)(_p)) = (_v) )
458
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v ) ( *((volatile UINT32*)(_p)) = (_v) )
459
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE64( _p, _v ) ( *((volatile UINT64*)(_p)) = (_v) )
460
    #else // Temporary workaround for CMake compilation issues on Windows. Assume X86/ADM64.
461
        #define SYMCRYPT_INTERNAL_VOLATILE_READ8( _p )    ( *((const volatile BYTE*)  (_p)) )
462
        #define SYMCRYPT_INTERNAL_VOLATILE_READ16( _p )   ( *((const volatile UINT16*)(_p)) )
463
        #define SYMCRYPT_INTERNAL_VOLATILE_READ32( _p )   ( *((const volatile UINT32*)(_p)) )
464
        #define SYMCRYPT_INTERNAL_VOLATILE_READ64( _p )   ( *((const volatile UINT64*)(_p)) )
465
466
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v )  ( *((volatile BYTE*)  (_p)) = (_v) )
467
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v ) ( *((volatile UINT16*)(_p)) = (_v) )
468
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v ) ( *((volatile UINT32*)(_p)) = (_v) )
469
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE64( _p, _v ) ( *((volatile UINT64*)(_p)) = (_v) )
470
    #endif
471
472
#elif SYMCRYPT_GNUC
473
474
    #if !SYMCRYPT_CPU_ARM
475
0
        #define SYMCRYPT_INTERNAL_VOLATILE_READ8( _p )    ( *((const volatile BYTE*)  (_p)) )
476
        #define SYMCRYPT_INTERNAL_VOLATILE_READ16( _p )   ( *((const volatile UINT16*)(_p)) )
477
10.1M
        #define SYMCRYPT_INTERNAL_VOLATILE_READ32( _p )   ( *((const volatile UINT32*)(_p)) )
478
        #define SYMCRYPT_INTERNAL_VOLATILE_READ64( _p )   ( *((const volatile UINT64*)(_p)) )
479
480
0
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v )  ( *((volatile BYTE*)  (_p)) = (_v) )
481
0
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v ) ( *((volatile UINT16*)(_p)) = (_v) )
482
303k
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v ) ( *((volatile UINT32*)(_p)) = (_v) )
483
20.4M
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE64( _p, _v ) ( *((volatile UINT64*)(_p)) = (_v) )
484
    #else // SYMCRYPT_CPU_ARM
485
        #define SYMCRYPT_INTERNAL_VOLATILE_READ8( _p )    ( *((const volatile BYTE*)  (_p)) )
486
        #define SYMCRYPT_INTERNAL_VOLATILE_READ16( _p )   ( *((const volatile UINT16*)(_p)) )
487
        #define SYMCRYPT_INTERNAL_VOLATILE_READ32( _p )   ( *((const volatile UINT32*)(_p)) )
488
        #define SYMCRYPT_INTERNAL_VOLATILE_READ64( p ) ( (UINT64)SYMCRYPT_INTERNAL_VOLATILE_READ32(&((PBYTE)p)[4]) << 32 |  SYMCRYPT_INTERNAL_VOLATILE_READ32(&((PBYTE)p)[0]) )
489
490
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v )  ( *((volatile BYTE*)  (_p)) = (_v) )
491
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v ) ( *((volatile UINT16*)(_p)) = (_v) )
492
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v ) ( *((volatile UINT32*)(_p)) = (_v) )
493
        #define SYMCRYPT_INTERNAL_VOLATILE_WRITE64( p, x ) { \
494
            SYMCRYPT_INTERNAL_VOLATILE_WRITE32( &((PBYTE)p)[0], (UINT32)((x)    ) );\
495
            SYMCRYPT_INTERNAL_VOLATILE_WRITE32( &((PBYTE)p)[4], (UINT32)(((UINT64)(x))>>32) );\
496
            }
497
    #endif
498
499
#else
500
501
    #error Unknown compiler
502
503
#endif
504
505
//
506
// FORCED MEMORY ACCESS
507
//
508
// These macros force a memory access. That is, they require that the memory
509
// read or write takes place, and do not allow the compiler to optimize the access
510
// away.
511
// They provide no other memory ordering requirements, so there are no acquire/release
512
// semantics, memory barriers, etc.
513
//
514
// The generic versions are implemented with a volatile access, but that is inefficient on some platforms
515
// because it might introduce memory ordering requirements.
516
//
517
518
0
#define SYMCRYPT_INTERNAL_FORCE_READ8( _p )    SYMCRYPT_INTERNAL_VOLATILE_READ8( _p )
519
#define SYMCRYPT_INTERNAL_FORCE_READ16( _p )   SYMCRYPT_INTERNAL_VOLATILE_READ16( _p )
520
10.1M
#define SYMCRYPT_INTERNAL_FORCE_READ32( _p )   SYMCRYPT_INTERNAL_VOLATILE_READ32( _p )
521
#define SYMCRYPT_INTERNAL_FORCE_READ64( _p )   SYMCRYPT_INTERNAL_VOLATILE_READ64( _p )
522
523
0
#define SYMCRYPT_INTERNAL_FORCE_WRITE8( _p, _v )  SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v )
524
0
#define SYMCRYPT_INTERNAL_FORCE_WRITE16( _p, _v ) SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v )
525
303k
#define SYMCRYPT_INTERNAL_FORCE_WRITE32( _p, _v ) SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v )
526
20.4M
#define SYMCRYPT_INTERNAL_FORCE_WRITE64( _p, _v ) SYMCRYPT_INTERNAL_VOLATILE_WRITE64( _p, _v )
527
528
//
529
// FIXED ENDIANNESS ACCESS
530
//
531
// Fixed endianness load and store
532
// We do this by platform because it affected by both endianness and alignment requirements
533
// The p pointer is always a pointer to BYTE
534
//
535
#if SYMCRYPT_MS_VC  // Microsoft VC++ Compiler
536
    #define SYMCRYPT_BSWAP16( x ) _byteswap_ushort(x)
537
    #define SYMCRYPT_BSWAP32( x ) _byteswap_ulong(x)
538
    #define SYMCRYPT_BSWAP64( x ) _byteswap_uint64(x)
539
#elif SYMCRYPT_GNUC
540
0
    #define SYMCRYPT_BSWAP16( x ) __builtin_bswap16(x)
541
20.3M
    #define SYMCRYPT_BSWAP32( x ) __builtin_bswap32(x)
542
9.07M
    #define SYMCRYPT_BSWAP64( x ) __builtin_bswap64(x)
543
#endif
544
545
#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM64
546
547
548
//
549
// X86, AMD64, ARM, and ARM64 have no alignment restrictions, and are little-endian.
550
// We do straight store/loads with BSWAPs where required.
551
// This technically relies upon on undefined behavior, as we assume the compiler will translate
552
// operations on unaligned pointers to 2, 4, and 8 bytes types to appropriately unaligned store/load
553
// instructions on these platforms (not just in these macros). This works for all compilers we
554
// currently use.
555
//
556
#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST16( p ) SYMCRYPT_BSWAP16( *((UINT16 *)(p)) )
557
0
#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST16( p )                 ( *((UINT16 *)(p)) )
558
20.2M
#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST32( p ) SYMCRYPT_BSWAP32( *((UINT32 *)(p)) )
559
15.5M
#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST32( p )                 ( *((UINT32 *)(p)) )
560
8.66M
#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST64( p ) SYMCRYPT_BSWAP64( *((UINT64 *)(p)) )
561
1.00M
#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST64( p )                 ( *((UINT64 *)(p)) )
562
563
0
#define SYMCRYPT_INTERNAL_STORE_MSBFIRST16( p, x ) ( *(UINT16 *)(p) = SYMCRYPT_BSWAP16(x) )
564
#define SYMCRYPT_INTERNAL_STORE_LSBFIRST16( p, x ) ( *(UINT16 *)(p) =                 (x) )
565
47.9k
#define SYMCRYPT_INTERNAL_STORE_MSBFIRST32( p, x ) ( *(UINT32 *)(p) = SYMCRYPT_BSWAP32(x) )
566
0
#define SYMCRYPT_INTERNAL_STORE_LSBFIRST32( p, x ) ( *(UINT32 *)(p) =                 (x) )
567
412k
#define SYMCRYPT_INTERNAL_STORE_MSBFIRST64( p, x ) ( *(UINT64 *)(p) = SYMCRYPT_BSWAP64(x) )
568
24.6k
#define SYMCRYPT_INTERNAL_STORE_LSBFIRST64( p, x ) ( *(UINT64 *)(p) =                 (x) )
569
570
#elif SYMCRYPT_CPU_ARM
571
572
//
573
// Only 64 bit accesses need to be aligned.
574
//
575
#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST16( p ) SYMCRYPT_BSWAP16( *((UINT16 *)(p)) )
576
#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST16( p )                 ( *((UINT16 *)(p)) )
577
#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST32( p ) SYMCRYPT_BSWAP32( *((UINT32 *)(p)) )
578
#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST32( p )                 ( *((UINT32 *)(p)) )
579
580
#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST64( p ) ( (UINT64)SYMCRYPT_INTERNAL_LOAD_MSBFIRST32(&((PBYTE)p)[0]) << 32 | SYMCRYPT_INTERNAL_LOAD_MSBFIRST32(&((PBYTE)p)[4]) )
581
#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST64( p ) ( (UINT64)SYMCRYPT_INTERNAL_LOAD_LSBFIRST32(&((PBYTE)p)[4]) << 32 | SYMCRYPT_INTERNAL_LOAD_LSBFIRST32(&((PBYTE)p)[0]) )
582
583
584
585
#define SYMCRYPT_INTERNAL_STORE_MSBFIRST16( p, x ) ( *(UINT16 *)(p) = SYMCRYPT_BSWAP16(x) )
586
#define SYMCRYPT_INTERNAL_STORE_LSBFIRST16( p, x ) ( *(UINT16 *)(p) =                 (x) )
587
#define SYMCRYPT_INTERNAL_STORE_MSBFIRST32( p, x ) ( *(UINT32 *)(p) = SYMCRYPT_BSWAP32(x) )
588
#define SYMCRYPT_INTERNAL_STORE_LSBFIRST32( p, x ) ( *(UINT32 *)(p) =                 (x) )
589
#define SYMCRYPT_INTERNAL_STORE_MSBFIRST64( p, x ) { \
590
    SYMCRYPT_INTERNAL_STORE_MSBFIRST32( &((PBYTE)p)[0],(UINT32)(((UINT64)(x))>>32) );\
591
    SYMCRYPT_INTERNAL_STORE_MSBFIRST32( &((PBYTE)p)[4],(UINT32)(x));\
592
    }
593
594
#define SYMCRYPT_INTERNAL_STORE_LSBFIRST64( p, x ) { \
595
    SYMCRYPT_INTERNAL_STORE_LSBFIRST32( &((PBYTE)p)[0], (UINT32)((x)    ) );\
596
    SYMCRYPT_INTERNAL_STORE_LSBFIRST32( &((PBYTE)p)[4], (UINT32)(((UINT64)(x))>>32) );\
597
    }
598
#else // unknown platform
599
600
//
601
// These functions have to handle arbitrary alignments too, so we do them byte-by-byte in the
602
// generic case.
603
// So far these macros have not been fully tested
604
//
605
#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST16( p ) ( ((UINT16)((PBYTE)p)[0]) << 8 | ((PBYTE)p)[1] )
606
#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST16( p ) ( ((UINT16)((PBYTE)p)[1]) << 8 | ((PBYTE)p)[0] )
607
#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST32( p ) ( (UINT32)SYMCRYPT_INTERNAL_LOAD_MSBFIRST16(&((PBYTE)p)[0]) << 16 | SYMCRYPT_INTERNAL_LOAD_MSBFIRST16(&((PBYTE)p)[2]) )
608
#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST32( p ) ( (UINT32)SYMCRYPT_INTERNAL_LOAD_LSBFIRST16(&((PBYTE)p)[2]) << 16 | SYMCRYPT_INTERNAL_LOAD_LSBFIRST16(&((PBYTE)p)[0]) )
609
#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST64( p ) ( (UINT64)SYMCRYPT_INTERNAL_LOAD_MSBFIRST32(&((PBYTE)p)[0]) << 32 | SYMCRYPT_INTERNAL_LOAD_MSBFIRST32(&((PBYTE)p)[4]) )
610
#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST64( p ) ( (UINT64)SYMCRYPT_INTERNAL_LOAD_LSBFIRST32(&((PBYTE)p)[4]) << 32 | SYMCRYPT_INTERNAL_LOAD_LSBFIRST32(&((PBYTE)p)[0]) )
611
612
#define SYMCRYPT_INTERNAL_STORE_MSBFIRST16( p, x ) { \
613
    ((PBYTE)p)[0] = (BYTE)((x)>> 8);\
614
    ((PBYTE)p)[1] = (BYTE)((x)    );\
615
    }
616
617
#define SYMCRYPT_INTERNAL_STORE_LSBFIRST16( p, x ) { \
618
    ((PBYTE)p)[0] = (BYTE)((x)    );\
619
    ((PBYTE)p)[1] = (BYTE)((x)>> 8);\
620
    }
621
622
#define SYMCRYPT_INTERNAL_STORE_MSBFIRST32( p, x ) { \
623
    ((PBYTE)p)[0] = (BYTE)((x)>>24);\
624
    ((PBYTE)p)[1] = (BYTE)((x)>>16);\
625
    ((PBYTE)p)[2] = (BYTE)((x)>> 8);\
626
    ((PBYTE)p)[3] = (BYTE)((x)    );\
627
    }
628
629
#define SYMCRYPT_INTERNAL_STORE_LSBFIRST32( p, x ) { \
630
    ((PBYTE)p)[0] = (BYTE)((x)    );\
631
    ((PBYTE)p)[1] = (BYTE)((x)>> 8);\
632
    ((PBYTE)p)[2] = (BYTE)((x)>>16);\
633
    ((PBYTE)p)[3] = (BYTE)((x)>>24);\
634
    }
635
636
#define SYMCRYPT_INTERNAL_STORE_MSBFIRST64( p, x ) { \
637
    SYMCRYPT_INTERNAL_STORE_MSBFIRST32( &((PBYTE)p)[0],(UINT32)(((UINT64)(x))>>32) );\
638
    SYMCRYPT_INTERNAL_STORE_MSBFIRST32( &((PBYTE)p)[4],(UINT32)(x));\
639
    }
640
641
#define SYMCRYPT_INTERNAL_STORE_LSBFIRST64( p, x ) { \
642
    SYMCRYPT_INTERNAL_STORE_LSBFIRST32( &((PBYTE)p)[0], (UINT32)((x)    ) );\
643
    SYMCRYPT_INTERNAL_STORE_LSBFIRST32( &((PBYTE)p)[4], (UINT32)(((UINT64)(x))>>32) );\
644
    }
645
646
#endif // platform switch for load/store macros
647
648
649
//==============================================================================================
650
//  INTERNAL DATA STRUCTURES
651
//==============================================================================================
652
//
653
// Note: we do not use the symbolic names like SYMCRYPT_SHA1_INPUT_BLOCK_SIZE as this
654
// file is included before that name is defined. Fixing that would make the public API header
655
// file harder to read by moving the constant away from the associated functions, or forcing
656
// the header file to use the struct name rather than the typedef. The current solution
657
// works quite well.
658
//
659
660
//-----------------------------------------------------------------
661
//     Block cipher description table
662
// Below are the typedefs for the block cipher description table type
663
// Callers can use this to define their own block cipher and use the block cipher
664
// modes.
665
//
666
667
typedef struct _SYMCRYPT_BLOCKCIPHER    SYMCRYPT_BLOCKCIPHER, *PSYMCRYPT_BLOCKCIPHER;
668
typedef const SYMCRYPT_BLOCKCIPHER  * PCSYMCRYPT_BLOCKCIPHER;
669
670
//
671
// Note that blockSize must be <= 32 and must be a power of two. This is true for all the block ciphers
672
// implemented in SymCrypt.
673
//
674
675
//
676
// HASH STATES
677
//
678
// All hash states have the same basic structure. This allows all hash implementations to share
679
// the same buffer management code. Some algorithms might still have optimized buffer management code
680
// specific for their algorithm, but most algs use the generic code.
681
// This is especially important for parallel hashing, where the buffer management & parallel organizational
682
// code are tightly coupled.
683
//
684
685
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_COMMON_HASH_STATE
686
{
687
                    UINT32                          bytesInBuffer;
688
                    SYMCRYPT_MAGIC_FIELD
689
                    UINT64                          dataLengthL;            // lower part of msg length
690
                    UINT64                          dataLengthH;            // upper part of msg length
691
    SYMCRYPT_ALIGN  BYTE                            buffer[SYMCRYPT_ANYSIZE_ARRAY];  // Size depends on algorithm
692
    // ...
693
    // Chaining state                                       // type/location depends on algorithm
694
    //
695
} SYMCRYPT_COMMON_HASH_STATE, *PSYMCRYPT_COMMON_HASH_STATE;
696
697
698
//
699
// SYMCRYPT_MD2_STATE
700
//
701
// Data structure that stores the state of an ongoing MD2 computation.
702
//
703
// The field names are from RFC 1319.
704
// It would be more efficient to store only the first 16 bytes of the X array,
705
// but that would complicate the code and MD2 isn't important enough to add
706
// extra complications.
707
//
708
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD2_CHAINING_STATE
709
{
710
    SYMCRYPT_ALIGN  BYTE    C[16];      // State for internal checksum computation
711
                    BYTE    X[48];      // State for actual hash chaining
712
} SYMCRYPT_MD2_CHAINING_STATE, *PSYMCRYPT_MD2_CHAINING_STATE;
713
714
//
715
// MD2 hash computation state.
716
//
717
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD2_STATE
718
{
719
                    UINT32                          bytesInBuffer;
720
                    SYMCRYPT_MAGIC_FIELD
721
                    UINT64                          dataLengthL;            // lower part of msg length
722
                    UINT64                          dataLengthH;            // upper part of msg length
723
    SYMCRYPT_ALIGN  BYTE                            buffer[16];             // buffer to keep one input block in
724
                    SYMCRYPT_MD2_CHAINING_STATE     chain;
725
} SYMCRYPT_MD2_STATE, *PSYMCRYPT_MD2_STATE;
726
typedef const SYMCRYPT_MD2_STATE *PCSYMCRYPT_MD2_STATE;
727
728
//
729
// SYMCRYPT_MD4_STATE
730
//
731
// Data structure that stores the state of an ongoing MD4 computation.
732
// The buffer contains dataLength % 64 bytes of data.
733
//
734
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD4_CHAINING_STATE
735
{
736
    UINT32   H[4];
737
} SYMCRYPT_MD4_CHAINING_STATE, *PSYMCRYPT_MD4_CHAINING_STATE;
738
739
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD4_STATE
740
{
741
                    UINT32                          bytesInBuffer;
742
                    SYMCRYPT_MAGIC_FIELD
743
                    UINT64                          dataLengthL;            // lower part of msg length
744
                    UINT64                          dataLengthH;            // upper part of msg length
745
    SYMCRYPT_ALIGN  BYTE                            buffer[64];             // buffer to keep one input block in
746
                    SYMCRYPT_MD4_CHAINING_STATE     chain;      // chaining state
747
} SYMCRYPT_MD4_STATE, *PSYMCRYPT_MD4_STATE;
748
typedef const SYMCRYPT_MD4_STATE *PCSYMCRYPT_MD4_STATE;
749
750
751
//
752
// SYMCRYPT_MD5_STATE
753
//
754
// Data structure that stores the state of an ongoing MD5 computation.
755
// The buffer contains dataLength % 64 bytes of data.
756
//
757
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD5_CHAINING_STATE
758
{
759
    UINT32   H[4];
760
} SYMCRYPT_MD5_CHAINING_STATE, *PSYMCRYPT_MD5_CHAINING_STATE;
761
762
763
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD5_STATE
764
{
765
                    UINT32                          bytesInBuffer;
766
                    SYMCRYPT_MAGIC_FIELD
767
                    UINT64                          dataLengthL;            // lower part of msg length
768
                    UINT64                          dataLengthH;            // upper part of msg length
769
    SYMCRYPT_ALIGN  BYTE                            buffer[64];             // buffer to keep one input block in
770
                    SYMCRYPT_MD5_CHAINING_STATE     chain;      // chaining state
771
} SYMCRYPT_MD5_STATE, *PSYMCRYPT_MD5_STATE;
772
typedef const SYMCRYPT_MD5_STATE *PCSYMCRYPT_MD5_STATE;
773
774
775
//
776
// SYMCRYPT_SHA1_STATE
777
//
778
// Data structure that stores the state of an ongoing SHA1 computation.
779
// The buffer contains dataLength % 64 bytes of data.
780
//
781
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA1_CHAINING_STATE
782
{
783
    UINT32   H[5];
784
} SYMCRYPT_SHA1_CHAINING_STATE, *PSYMCRYPT_SHA1_CHAINING_STATE;
785
786
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA1_STATE
787
{
788
                    UINT32                          bytesInBuffer;
789
                    SYMCRYPT_MAGIC_FIELD
790
                    UINT64                          dataLengthL;            // lower part of msg length
791
                    UINT64                          dataLengthH;            // upper part of msg length
792
    SYMCRYPT_ALIGN  BYTE                            buffer[64];             // buffer to keep one input block in
793
                    SYMCRYPT_SHA1_CHAINING_STATE    chain;      // chaining state
794
} SYMCRYPT_SHA1_STATE, *PSYMCRYPT_SHA1_STATE;
795
typedef const SYMCRYPT_SHA1_STATE *PCSYMCRYPT_SHA1_STATE;
796
797
798
//
799
// SYMCRYPT_SHA256_STATE
800
//
801
// Data structure that stores the state of an ongoing SHA256 computation.
802
// The buffer contains dataLength % 64 bytes of data.
803
//
804
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA256_CHAINING_STATE
805
{
806
    SYMCRYPT_ALIGN  UINT32   H[8];
807
} SYMCRYPT_SHA256_CHAINING_STATE, * PSYMCRYPT_SHA256_CHAINING_STATE;
808
809
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA256_STATE
810
{
811
                    UINT32                          bytesInBuffer;
812
                    SYMCRYPT_MAGIC_FIELD
813
                    UINT64                          dataLengthL;            // lower part of msg length
814
                    UINT64                          dataLengthH;            // upper part of msg length
815
    SYMCRYPT_ALIGN  BYTE                            buffer[64];             // buffer to keep one input block in
816
                    SYMCRYPT_SHA256_CHAINING_STATE  chain;      // chaining state
817
} SYMCRYPT_SHA256_STATE, *PSYMCRYPT_SHA256_STATE;
818
typedef const SYMCRYPT_SHA256_STATE *PCSYMCRYPT_SHA256_STATE;
819
820
821
//
822
// SYMCRYPT_SHA512_STATE
823
//
824
// Data structure that stores the state of an ongoing SHA512 computation.
825
// The buffer contains dataLength % 128 bytes of data.
826
//
827
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA512_CHAINING_STATE
828
{
829
    UINT64   H[8];
830
} SYMCRYPT_SHA512_CHAINING_STATE, *PSYMCRYPT_SHA512_CHAINING_STATE;
831
832
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA512_STATE
833
{
834
                    UINT32                          bytesInBuffer;
835
                    SYMCRYPT_MAGIC_FIELD
836
                    UINT64                          dataLengthL;            // lower part of msg length
837
                    UINT64                          dataLengthH;            // upper part of msg length
838
    SYMCRYPT_ALIGN  BYTE                            buffer[128];            // buffer to keep one input block in
839
                    SYMCRYPT_SHA512_CHAINING_STATE  chain;          // chaining state
840
} SYMCRYPT_SHA512_STATE, *PSYMCRYPT_SHA512_STATE;
841
typedef const SYMCRYPT_SHA512_STATE *PCSYMCRYPT_SHA512_STATE;
842
843
844
//
845
// SYMCRYPT_SHA384_STATE
846
//
847
// This is identical to the SHA512.
848
//
849
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA384_STATE
850
{
851
    UINT32                          bytesInBuffer;
852
    SYMCRYPT_MAGIC_FIELD
853
    UINT64                          dataLengthL;            // lower part of msg length
854
    UINT64                          dataLengthH;            // upper part of msg length
855
    SYMCRYPT_ALIGN  BYTE            buffer[128];            // buffer to keep one input block in
856
    SYMCRYPT_SHA512_CHAINING_STATE  chain;          // chaining state
857
} SYMCRYPT_SHA384_STATE, *PSYMCRYPT_SHA384_STATE;
858
typedef const SYMCRYPT_SHA384_STATE *PCSYMCRYPT_SHA384_STATE;
859
860
//
861
// SYMCRYPT_KECCAK_STATE
862
//
863
// Data structure that stores the state of an ongoing SHA-3 derived algorithm computation.
864
// 
865
866
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_KECCAK_STATE
867
{
868
    SYMCRYPT_ALIGN  UINT64  state[25];      // state for Keccak-f[1600] permutation
869
    UINT32                  inputBlockSize; // rate
870
    UINT32                  stateIndex;     // position in the state for next merge/extract operation
871
    UINT8                   paddingValue;   // Keccak padding value
872
    BOOLEAN                 squeezeMode;    // denotes whether the state is in squeeze mode
873
} SYMCRYPT_KECCAK_STATE, *PSYMCRYPT_KECCAK_STATE;
874
typedef const SYMCRYPT_KECCAK_STATE *PCSYMCRYPT_KECCAK_STATE;
875
876
//
877
// SYMCRYPT_SHA3_256_STATE
878
//
879
// Data structure that stores the state of an ongoing SHA3-256 computation.
880
//
881
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA3_256_STATE
882
{
883
    SYMCRYPT_KECCAK_STATE   ks;
884
    SYMCRYPT_MAGIC_FIELD
885
} SYMCRYPT_SHA3_256_STATE, * PSYMCRYPT_SHA3_256_STATE;
886
typedef const SYMCRYPT_SHA3_256_STATE* PCSYMCRYPT_SHA3_256_STATE;
887
888
//
889
// SYMCRYPT_SHA3_384_STATE
890
//
891
// Data structure that stores the state of an ongoing SHA3-384 computation.
892
//
893
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA3_384_STATE
894
{
895
    SYMCRYPT_KECCAK_STATE   ks;
896
    SYMCRYPT_MAGIC_FIELD
897
} SYMCRYPT_SHA3_384_STATE, * PSYMCRYPT_SHA3_384_STATE;
898
typedef const SYMCRYPT_SHA3_384_STATE* PCSYMCRYPT_SHA3_384_STATE;
899
900
//
901
// SYMCRYPT_SHA3_512_STATE
902
//
903
// Data structure that stores the state of an ongoing SHA3-512 computation.
904
//
905
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA3_512_STATE
906
{
907
    SYMCRYPT_KECCAK_STATE   ks;
908
    SYMCRYPT_MAGIC_FIELD
909
} SYMCRYPT_SHA3_512_STATE, * PSYMCRYPT_SHA3_512_STATE;
910
typedef const SYMCRYPT_SHA3_512_STATE* PCSYMCRYPT_SHA3_512_STATE;
911
912
//
913
// SYMCRYPT_SHAKE128_STATE
914
//
915
// Data structure that stores the state of an ongoing SHAKE128 computation.
916
//
917
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHAKE128_STATE
918
{
919
    SYMCRYPT_KECCAK_STATE   ks;
920
    SYMCRYPT_MAGIC_FIELD
921
} SYMCRYPT_SHAKE128_STATE, * PSYMCRYPT_SHAKE128_STATE;
922
typedef const SYMCRYPT_SHAKE128_STATE* PCSYMCRYPT_SHAKE128_STATE;
923
924
//
925
// SYMCRYPT_SHAKE256_STATE
926
//
927
// Data structure that stores the state of an ongoing SHAKE256 computation.
928
//
929
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHAKE256_STATE
930
{
931
    SYMCRYPT_KECCAK_STATE   ks;
932
    SYMCRYPT_MAGIC_FIELD
933
} SYMCRYPT_SHAKE256_STATE, * PSYMCRYPT_SHAKE256_STATE;
934
typedef const SYMCRYPT_SHAKE256_STATE* PCSYMCRYPT_SHAKE256_STATE;
935
936
//
937
// SYMCRYPT_CSHAKE128_STATE
938
//
939
// Data structure that stores the state of an ongoing CSHAKE128 computation.
940
//
941
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_CSHAKE128_STATE
942
{
943
    SYMCRYPT_KECCAK_STATE   ks;
944
    SYMCRYPT_MAGIC_FIELD
945
} SYMCRYPT_CSHAKE128_STATE, * PSYMCRYPT_CSHAKE128_STATE;
946
typedef const SYMCRYPT_CSHAKE128_STATE* PCSYMCRYPT_CSHAKE128_STATE;
947
948
//
949
// SYMCRYPT_CSHAKE256_STATE
950
//
951
// Data structure that stores the state of an ongoing CSHAKE256 computation.
952
//
953
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_CSHAKE256_STATE
954
{
955
    SYMCRYPT_KECCAK_STATE   ks;
956
    SYMCRYPT_MAGIC_FIELD
957
} SYMCRYPT_CSHAKE256_STATE, * PSYMCRYPT_CSHAKE256_STATE;
958
typedef const SYMCRYPT_CSHAKE256_STATE* PCSYMCRYPT_CSHAKE256_STATE;
959
960
//
961
// SYMCRYPT_KMAC128_EXPANDED_KEY
962
//
963
// Data structure that stores the expanded key for KMAC128.
964
//
965
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_KMAC128_EXPANDED_KEY
966
{
967
    SYMCRYPT_KECCAK_STATE   ks;
968
    SYMCRYPT_MAGIC_FIELD
969
} SYMCRYPT_KMAC128_EXPANDED_KEY, * PSYMCRYPT_KMAC128_EXPANDED_KEY;
970
typedef const SYMCRYPT_KMAC128_EXPANDED_KEY* PCSYMCRYPT_KMAC128_EXPANDED_KEY;
971
972
//
973
// SYMCRYPT_KMAC128_STATE
974
//
975
// Data structure that stores the state of an ongoing KMAC128 computation.
976
//
977
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_KMAC128_STATE
978
{
979
    SYMCRYPT_KECCAK_STATE   ks;
980
    SYMCRYPT_MAGIC_FIELD
981
} SYMCRYPT_KMAC128_STATE, * PSYMCRYPT_KMAC128_STATE;
982
typedef const SYMCRYPT_KMAC128_STATE* PCSYMCRYPT_KMAC128_STATE;
983
984
//
985
// SYMCRYPT_KMAC256_EXPANDED_KEY
986
//
987
// Data structure that stores the expanded key for KMAC256.
988
//
989
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_KMAC256_EXPANDED_KEY
990
{
991
    SYMCRYPT_KECCAK_STATE   ks;
992
    SYMCRYPT_MAGIC_FIELD
993
} SYMCRYPT_KMAC256_EXPANDED_KEY, * PSYMCRYPT_KMAC256_EXPANDED_KEY;
994
typedef const SYMCRYPT_KMAC256_EXPANDED_KEY* PCSYMCRYPT_KMAC256_EXPANDED_KEY;
995
996
//
997
// SYMCRYPT_KMAC256_STATE
998
//
999
// Data structure that stores the state of an ongoing KMAC256 computation.
1000
//
1001
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_KMAC256_STATE
1002
{
1003
    SYMCRYPT_KECCAK_STATE   ks;
1004
    SYMCRYPT_MAGIC_FIELD
1005
} SYMCRYPT_KMAC256_STATE, * PSYMCRYPT_KMAC256_STATE;
1006
typedef const SYMCRYPT_KMAC256_STATE* PCSYMCRYPT_KMAC256_STATE;
1007
1008
1009
//
1010
// Generic hashing
1011
//
1012
typedef union _SYMCRYPT_HASH_STATE
1013
{
1014
    SYMCRYPT_MD2_STATE      md2State;
1015
    SYMCRYPT_MD4_STATE      md4State;
1016
    SYMCRYPT_MD5_STATE      md5State;
1017
    SYMCRYPT_SHA1_STATE     sha1State;
1018
    SYMCRYPT_SHA256_STATE   sha256State;
1019
    SYMCRYPT_SHA384_STATE   sha384State;
1020
    SYMCRYPT_SHA512_STATE   sha512State;
1021
    SYMCRYPT_SHA3_256_STATE sha3_256State;
1022
    SYMCRYPT_SHA3_384_STATE sha3_384State;
1023
    SYMCRYPT_SHA3_512_STATE sha3_512State;
1024
} SYMCRYPT_HASH_STATE, *PSYMCRYPT_HASH_STATE;
1025
typedef const SYMCRYPT_HASH_STATE *PCSYMCRYPT_HASH_STATE;
1026
1027
0
#define SYMCRYPT_HASH_MAX_RESULT_SIZE    SYMCRYPT_SHA512_RESULT_SIZE
1028
1029
SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HASH;
1030
SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_PARALLEL_HASH;
1031
1032
typedef struct _SYMCRYPT_HASH SYMCRYPT_HASH, *PSYMCRYPT_HASH;
1033
typedef const SYMCRYPT_HASH  *PCSYMCRYPT_HASH;
1034
typedef struct _SYMCRYPT_PARALLEL_HASH SYMCRYPT_PARALLEL_HASH, *PSYMCRYPT_PARALLEL_HASH;
1035
typedef const SYMCRYPT_PARALLEL_HASH  *PCSYMCRYPT_PARALLEL_HASH;
1036
1037
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_INIT_FUNC)             ( PVOID pState );
1038
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_APPEND_FUNC)           ( PVOID pState, PCBYTE pbData, SIZE_T cbData );
1039
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_RESULT_FUNC)           ( PVOID pState, PVOID pbResult );
1040
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_APPEND_BLOCKS_FUNC)    ( PVOID pChain, PCBYTE pbData, SIZE_T cbData, SIZE_T * pcbRemaining );
1041
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_STATE_COPY_FUNC)       ( PCVOID pStateSrc, PVOID pStateDst );
1042
1043
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HASH
1044
{
1045
    PSYMCRYPT_HASH_INIT_FUNC            initFunc;
1046
    PSYMCRYPT_HASH_APPEND_FUNC          appendFunc;
1047
    PSYMCRYPT_HASH_RESULT_FUNC          resultFunc;
1048
    PSYMCRYPT_HASH_APPEND_BLOCKS_FUNC   appendBlockFunc;
1049
    PSYMCRYPT_HASH_STATE_COPY_FUNC      stateCopyFunc;
1050
    UINT32                              stateSize;          // sizeof( hash state )
1051
    UINT32                              resultSize;         // size of hash result
1052
    UINT32                              inputBlockSize;
1053
    UINT32                              chainOffset;        // offset into state structure of the chaining state
1054
    UINT32                              chainSize;          // size of chaining state
1055
} SYMCRYPT_HASH, *PSYMCRYPT_HASH;
1056
1057
1058
//
1059
// Parallel hashing
1060
//
1061
1062
#if SYMCRYPT_CPU_ARM
1063
#define SYMCRYPT_PARALLEL_SHA256_MIN_PARALLELISM    (3)
1064
#define SYMCRYPT_PARALLEL_SHA256_MAX_PARALLELISM    (4)
1065
#else
1066
#define SYMCRYPT_PARALLEL_SHA256_MIN_PARALLELISM    (2)
1067
#define SYMCRYPT_PARALLEL_SHA256_MAX_PARALLELISM    (8)
1068
#endif
1069
1070
typedef enum _SYMCRYPT_HASH_OPERATION_TYPE {
1071
    SYMCRYPT_HASH_OPERATION_APPEND = 1,
1072
    SYMCRYPT_HASH_OPERATION_RESULT = 2,
1073
} SYMCRYPT_HASH_OPERATION_TYPE;
1074
1075
typedef struct _SYMCRYPT_PARALLEL_HASH_OPERATION    SYMCRYPT_PARALLEL_HASH_OPERATION, *PSYMCRYPT_PARALLEL_HASH_OPERATION;
1076
typedef const SYMCRYPT_PARALLEL_HASH_OPERATION *PCSYMRYPT_PARALLEL_HASH_OPERATION;
1077
1078
struct _SYMCRYPT_PARALLEL_HASH_OPERATION {
1079
                                SIZE_T                              iHash;          // index of hash object into the state array
1080
                                SYMCRYPT_HASH_OPERATION_TYPE        hashOperation;  // operation to be performed
1081
    _Field_size_( cbBuffer )    PBYTE                               pbBuffer;       // data to be hashed, or result buffer
1082
                                SIZE_T                              cbBuffer;       // size of pbData buffer.
1083
                                PSYMCRYPT_PARALLEL_HASH_OPERATION   next;           // internal scratch space; do not use.
1084
};
1085
1086
1087
SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_PARALLEL_HASH_SCRATCH_OPERATION; // as yet unspecified struct
1088
typedef struct _SYMCRYPT_PARALLEL_HASH_SCRATCH_OPERATION
1089
        SYMCRYPT_PARALLEL_HASH_SCRATCH_OPERATION, *PSYMCRYPT_PARALLEL_HASH_SCRATCH_OPERATION;
1090
1091
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_PARALLEL_HASH_SCRATCH_STATE {
1092
    PVOID                               hashState;          // the actual hash state
1093
    BYTE                                processingState;
1094
    BYTE                                bytesAlreadyProcessed;  // of the next Append operation
1095
    UINT64                              bytes;              // # bytes left to process on this state
1096
    PSYMCRYPT_PARALLEL_HASH_OPERATION   next;               // next operation to be performed.
1097
    PCBYTE                              pbData;             // data/size of ongoing append operation; this op has already been removed from the next linked list
1098
    SIZE_T                              cbData;
1099
}SYMCRYPT_PARALLEL_HASH_SCRATCH_STATE, *PSYMCRYPT_PARALLEL_HASH_SCRATCH_STATE;
1100
1101
1102
//
1103
// The scratch space used by parallel SHA-256 consists of three regions:
1104
// - an array of SYMCRYPT_PARALLEL_HASH_SCRATCH_STATE structures, aligned to SYMCRYPT_ALIGN_VALUE.
1105
// - the work array, an array of pointers to SYMCRYPT_PARALLEL_HASH_SCRATCH_STATEs.
1106
// - an array of 4 + 8 + 64 SIMD vector elements, aligned to the size of those elements.
1107
//
1108
//
1109
#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64
1110
#define SYMCRYPT_SIMD_ELEMENT_SIZE  32
1111
#elif SYMCRYPT_CPU_ARM | SYMCRYPT_CPU_ARM64
1112
#define SYMCRYPT_SIMD_ELEMENT_SIZE  16
1113
#elif SYMCRYPT_CPU_UNKNOWN
1114
#define SYMCRYPT_SIMD_ELEMENT_SIZE  0
1115
#else
1116
#error Unknown CPU
1117
#endif
1118
1119
#define SYMCRYPT_PARALLEL_SHA256_FIXED_SCRATCH  ( (4 + 8 + 64) * SYMCRYPT_SIMD_ELEMENT_SIZE + SYMCRYPT_SIMD_ELEMENT_SIZE - 1  + SYMCRYPT_ALIGN_VALUE - 1 )
1120
#define SYMCRYPT_PARALLEL_SHA384_FIXED_SCRATCH  ( (4 + 8 + 80) * SYMCRYPT_SIMD_ELEMENT_SIZE + SYMCRYPT_SIMD_ELEMENT_SIZE - 1  + SYMCRYPT_ALIGN_VALUE - 1 )
1121
#define SYMCRYPT_PARALLEL_SHA512_FIXED_SCRATCH  ( (4 + 8 + 80) * SYMCRYPT_SIMD_ELEMENT_SIZE + SYMCRYPT_SIMD_ELEMENT_SIZE - 1  + SYMCRYPT_ALIGN_VALUE - 1 )
1122
#define SYMCRYPT_PARALLEL_HASH_PER_STATE_SCRATCH  (sizeof( SYMCRYPT_PARALLEL_HASH_SCRATCH_STATE ) + sizeof( PSYMCRYPT_PARALLEL_HASH_SCRATCH_STATE ) )
1123
1124
SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_PARALLEL_HASH;
1125
typedef struct _SYMCRYPT_PARALLEL_HASH SYMCRYPT_PARALLEL_HASH, *PSYMCRYPT_PARALLEL_HASH;
1126
typedef const SYMCRYPT_PARALLEL_HASH  *PCSYMCRYPT_PARALLEL_HASH;
1127
1128
typedef BOOLEAN (SYMCRYPT_CALL * PSYMCRYPT_PARALLEL_HASH_RESULT_FUNC) (PCSYMCRYPT_PARALLEL_HASH pParHash, PSYMCRYPT_COMMON_HASH_STATE pState, PSYMCRYPT_PARALLEL_HASH_SCRATCH_STATE pScratch, BOOLEAN *pRes );
1129
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_PARALLEL_HASH_RESULT_DONE_FUNC ) (PCSYMCRYPT_PARALLEL_HASH pParHash, PSYMCRYPT_COMMON_HASH_STATE pState, PCSYMRYPT_PARALLEL_HASH_OPERATION pOp);
1130
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_PARALLEL_APPEND_FUNC) (
1131
    _Inout_updates_( nPar )                 PSYMCRYPT_PARALLEL_HASH_SCRATCH_STATE * pWork,
1132
                                            SIZE_T                                  nPar,
1133
                                            SIZE_T                                  nBytes,
1134
    _Out_writes_( cbSimdScratch )           PBYTE                                   pbSimdScratch,
1135
                                            SIZE_T                                  cbSimdScratch );
1136
1137
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_PARALLEL_HASH
1138
{
1139
    PCSYMCRYPT_HASH                             pHash;
1140
    UINT32                                      parScratchFixed;    // fixed scratch size for parallel hash
1141
    PSYMCRYPT_PARALLEL_HASH_RESULT_FUNC         parResult1Func;
1142
    PSYMCRYPT_PARALLEL_HASH_RESULT_FUNC         parResult2Func;
1143
    PSYMCRYPT_PARALLEL_HASH_RESULT_DONE_FUNC    parResultDoneFunc;
1144
1145
    PSYMCRYPT_PARALLEL_APPEND_FUNC              parAppendFunc;
1146
} SYMCRYPT_PARALLEL_HASH, *PSYMCRYPT_PARALLEL_HASH;
1147
1148
1149
//======================================================================================================
1150
// MAC
1151
//
1152
1153
1154
//
1155
// SYMCRYPT_HMAC_MD5_EXPANDED_KEY
1156
//
1157
// Data structure to store an expanded key for HMAC-MD5.
1158
//
1159
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_MD5_EXPANDED_KEY
1160
{
1161
    SYMCRYPT_MD5_CHAINING_STATE     innerState;
1162
    SYMCRYPT_MD5_CHAINING_STATE     outerState;
1163
    SYMCRYPT_MAGIC_FIELD
1164
} SYMCRYPT_HMAC_MD5_EXPANDED_KEY, *PSYMCRYPT_HMAC_MD5_EXPANDED_KEY;
1165
typedef const SYMCRYPT_HMAC_MD5_EXPANDED_KEY * PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY;
1166
1167
//
1168
// SYMCRYPT_HMAC_MD5_STATE
1169
//
1170
// Data structure that encodes an ongoing HMAC-MD5 computation.
1171
//
1172
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_MD5_STATE
1173
{
1174
    SYMCRYPT_MD5_STATE                 hash;
1175
    PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY   pKey;
1176
    SYMCRYPT_MAGIC_FIELD
1177
} SYMCRYPT_HMAC_MD5_STATE, *PSYMCRYPT_HMAC_MD5_STATE;
1178
typedef const SYMCRYPT_HMAC_MD5_STATE *PCSYMCRYPT_HMAC_MD5_STATE;
1179
1180
1181
//
1182
// SYMCRYPT_HMAC_SHA1_EXPANDED_KEY
1183
//
1184
// Data structure to store an expanded key for HMAC-SHA1.
1185
//
1186
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA1_EXPANDED_KEY
1187
{
1188
    SYMCRYPT_SHA1_CHAINING_STATE    innerState;
1189
    SYMCRYPT_SHA1_CHAINING_STATE    outerState;
1190
    SYMCRYPT_MAGIC_FIELD
1191
} SYMCRYPT_HMAC_SHA1_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA1_EXPANDED_KEY;
1192
typedef const SYMCRYPT_HMAC_SHA1_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA1_EXPANDED_KEY;
1193
1194
//
1195
// SYMCRYPT_HMAC_SHA1_STATE
1196
//
1197
// Data structure that encodes an ongoing HMAC-SHA1 computation.
1198
//
1199
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA1_STATE
1200
{
1201
    SYMCRYPT_SHA1_STATE                 hash;
1202
    PCSYMCRYPT_HMAC_SHA1_EXPANDED_KEY   pKey;
1203
    SYMCRYPT_MAGIC_FIELD
1204
} SYMCRYPT_HMAC_SHA1_STATE, *PSYMCRYPT_HMAC_SHA1_STATE;
1205
typedef const SYMCRYPT_HMAC_SHA1_STATE *PCSYMCRYPT_HMAC_SHA1_STATE;
1206
1207
1208
//
1209
// SYMCRYPT_HMAC_SHA256_EXPANDED_KEY
1210
//
1211
// Data structure to store an expanded key for HMAC-SHA256.
1212
//
1213
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA256_EXPANDED_KEY
1214
{
1215
    SYMCRYPT_SHA256_CHAINING_STATE  innerState;
1216
    SYMCRYPT_SHA256_CHAINING_STATE  outerState;
1217
    SYMCRYPT_MAGIC_FIELD
1218
} SYMCRYPT_HMAC_SHA256_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA256_EXPANDED_KEY;
1219
typedef const SYMCRYPT_HMAC_SHA256_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA256_EXPANDED_KEY;
1220
1221
//
1222
// SYMCRYPT_HMAC_SHA256_STATE
1223
//
1224
// Data structure that encodes an ongoing HMAC-SHA256 computation.
1225
//
1226
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA256_STATE
1227
{
1228
    SYMCRYPT_SHA256_STATE                 hash;
1229
    PCSYMCRYPT_HMAC_SHA256_EXPANDED_KEY   pKey;
1230
    SYMCRYPT_MAGIC_FIELD
1231
} SYMCRYPT_HMAC_SHA256_STATE, *PSYMCRYPT_HMAC_SHA256_STATE;
1232
typedef const SYMCRYPT_HMAC_SHA256_STATE *PCSYMCRYPT_HMAC_SHA256_STATE;
1233
1234
1235
//
1236
// SYMCRYPT_HMAC_SHA384_EXPANDED_KEY
1237
//
1238
// Data structure to store an expanded key for HMAC-SHA384.
1239
//
1240
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA384_EXPANDED_KEY
1241
{
1242
    SYMCRYPT_SHA512_CHAINING_STATE  innerState;
1243
    SYMCRYPT_SHA512_CHAINING_STATE  outerState;
1244
    SYMCRYPT_MAGIC_FIELD
1245
} SYMCRYPT_HMAC_SHA384_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA384_EXPANDED_KEY;
1246
typedef const SYMCRYPT_HMAC_SHA384_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA384_EXPANDED_KEY;
1247
1248
//
1249
// SYMCRYPT_HMAC_SHA384_STATE
1250
//
1251
// Data structure that encodes an ongoing HMAC-SHA384 computation.
1252
//
1253
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA384_STATE
1254
{
1255
    SYMCRYPT_SHA384_STATE                 hash;
1256
    PCSYMCRYPT_HMAC_SHA384_EXPANDED_KEY   pKey;
1257
    SYMCRYPT_MAGIC_FIELD
1258
} SYMCRYPT_HMAC_SHA384_STATE, *PSYMCRYPT_HMAC_SHA384_STATE;
1259
typedef const SYMCRYPT_HMAC_SHA384_STATE *PCSYMCRYPT_HMAC_SHA384_STATE;
1260
1261
//
1262
// SYMCRYPT_HMAC_SHA512_EXPANDED_KEY
1263
//
1264
// Data structure to store an expanded key for HMAC-SHA512.
1265
//
1266
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA512_EXPANDED_KEY
1267
{
1268
    SYMCRYPT_SHA512_CHAINING_STATE  innerState;
1269
    SYMCRYPT_SHA512_CHAINING_STATE  outerState;
1270
    SYMCRYPT_MAGIC_FIELD
1271
} SYMCRYPT_HMAC_SHA512_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA512_EXPANDED_KEY;
1272
typedef const SYMCRYPT_HMAC_SHA512_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA512_EXPANDED_KEY;
1273
1274
//
1275
// SYMCRYPT_HMAC_SHA512_STATE
1276
//
1277
// Data structure that encodes an ongoing HMAC-SHA512 computation.
1278
//
1279
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA512_STATE
1280
{
1281
    SYMCRYPT_SHA512_STATE                 hash;
1282
    PCSYMCRYPT_HMAC_SHA512_EXPANDED_KEY   pKey;
1283
    SYMCRYPT_MAGIC_FIELD
1284
} SYMCRYPT_HMAC_SHA512_STATE, *PSYMCRYPT_HMAC_SHA512_STATE;
1285
typedef const SYMCRYPT_HMAC_SHA512_STATE *PCSYMCRYPT_HMAC_SHA512_STATE;
1286
1287
//
1288
// SYMCRYPT_HMAC_EXPANDED_KEY
1289
//
1290
// Generic HMAC Expanded Key data structure
1291
//
1292
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_EXPANDED_KEY
1293
{
1294
    PCSYMCRYPT_HASH     pHash;
1295
    SYMCRYPT_HASH_STATE innerState;
1296
    SYMCRYPT_HASH_STATE outerState;
1297
    SYMCRYPT_MAGIC_FIELD
1298
} SYMCRYPT_HMAC_EXPANDED_KEY, * PSYMCRYPT_HMAC_EXPANDED_KEY;
1299
typedef const SYMCRYPT_HMAC_EXPANDED_KEY* PCSYMCRYPT_HMAC_EXPANDED_KEY;
1300
1301
//
1302
// SYMCRYPT_HMAC_STATE
1303
//
1304
// Generic HMAC data structure
1305
//
1306
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_STATE
1307
{
1308
    PCSYMCRYPT_HMAC_EXPANDED_KEY    pKey;
1309
    SYMCRYPT_HASH_STATE             hash;
1310
    SYMCRYPT_MAGIC_FIELD
1311
} SYMCRYPT_HMAC_STATE, * PSYMCRYPT_HMAC_STATE;
1312
typedef const SYMCRYPT_HMAC_STATE* PCSYMCRYPT_HMAC_STATE;
1313
1314
//
1315
// SYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY
1316
//
1317
// Data structure to store an expanded key for HMAC-SHA3-256
1318
//
1319
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY
1320
{
1321
    SYMCRYPT_HMAC_EXPANDED_KEY  generic;
1322
1323
} SYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY;
1324
typedef const SYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY;
1325
1326
//
1327
// SYMCRYPT_HMAC_SHA3_256_STATE
1328
//
1329
// Data structure that encodes an ongoing HMAC-SHA3-256 computation.
1330
//
1331
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_256_STATE
1332
{
1333
    SYMCRYPT_HMAC_STATE generic;
1334
1335
} SYMCRYPT_HMAC_SHA3_256_STATE, *PSYMCRYPT_HMAC_SHA3_256_STATE;
1336
typedef const SYMCRYPT_HMAC_SHA3_256_STATE *PCSYMCRYPT_HMAC_SHA3_256_STATE;
1337
1338
//
1339
// SYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY
1340
//
1341
// Data structure to store an expanded key for HMAC-SHA3-384
1342
//
1343
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY
1344
{
1345
    SYMCRYPT_HMAC_EXPANDED_KEY  generic;
1346
1347
} SYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY;
1348
typedef const SYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY;
1349
1350
//
1351
// SYMCRYPT_HMAC_SHA3_384_STATE
1352
//
1353
// Data structure that encodes an ongoing HMAC-SHA3-384 computation.
1354
//
1355
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_384_STATE
1356
{
1357
    SYMCRYPT_HMAC_STATE generic;
1358
1359
} SYMCRYPT_HMAC_SHA3_384_STATE, *PSYMCRYPT_HMAC_SHA3_384_STATE;
1360
typedef const SYMCRYPT_HMAC_SHA3_384_STATE *PCSYMCRYPT_HMAC_SHA3_384_STATE;
1361
1362
//
1363
// SYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY
1364
//
1365
// Data structure to store an expanded key for HMAC-SHA3-512
1366
//
1367
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY
1368
{
1369
    SYMCRYPT_HMAC_EXPANDED_KEY  generic;
1370
1371
} SYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY;
1372
typedef const SYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY;
1373
1374
//
1375
// SYMCRYPT_HMAC_SHA3_512_STATE
1376
//
1377
// Data structure that encodes an ongoing HMAC-SHA3-512 computation.
1378
//
1379
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_512_STATE
1380
{
1381
    SYMCRYPT_HMAC_STATE generic;
1382
1383
} SYMCRYPT_HMAC_SHA3_512_STATE, *PSYMCRYPT_HMAC_SHA3_512_STATE;
1384
typedef const SYMCRYPT_HMAC_SHA3_512_STATE *PCSYMCRYPT_HMAC_SHA3_512_STATE;
1385
1386
//
1387
// SYMCRYPT_AES_EXPANDED_KEY
1388
//
1389
// Expanded key for AES operattions.
1390
//
1391
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_AES_EXPANDED_KEY {
1392
    SYMCRYPT_ALIGN BYTE RoundKey[29][4][4];
1393
        // Round keys, first the encryption round keys in encryption order,
1394
        // followed by the decryption round keys in decryption order.
1395
        // The first decryption round key is the last encryption round key.
1396
        // AES-256 has 14 rounds and thus 15 round keys for encryption and 15
1397
        // for decryption. As they share one round key, we need room for 29.
1398
    BYTE   (*lastEncRoundKey)[4][4];    // Pointer to last encryption round key
1399
                                        // also the first round key for decryption
1400
    BYTE   (*lastDecRoundKey)[4][4];    // Pointer to last decryption round key.
1401
1402
    SYMCRYPT_MAGIC_FIELD
1403
} SYMCRYPT_AES_EXPANDED_KEY, *PSYMCRYPT_AES_EXPANDED_KEY;
1404
typedef const SYMCRYPT_AES_EXPANDED_KEY * PCSYMCRYPT_AES_EXPANDED_KEY;
1405
1406
//
1407
// AES-CMAC
1408
//
1409
// Note: SYMCRYPT_AES_BLOCK_SIZE is not yet defined, so we use
1410
// literal constants instead.
1411
//
1412
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_AES_CMAC_EXPANDED_KEY
1413
{
1414
    SYMCRYPT_AES_EXPANDED_KEY   aesKey;
1415
    BYTE                        K1[16];
1416
    BYTE                        K2[16];
1417
    SYMCRYPT_MAGIC_FIELD
1418
} SYMCRYPT_AES_CMAC_EXPANDED_KEY, *PSYMCRYPT_AES_CMAC_EXPANDED_KEY;
1419
typedef const SYMCRYPT_AES_CMAC_EXPANDED_KEY * PCSYMCRYPT_AES_CMAC_EXPANDED_KEY;
1420
1421
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_AES_CMAC_STATE
1422
{
1423
    BYTE                                chain[16];
1424
    BYTE                                buf[16];
1425
    SIZE_T                              bytesInBuf;
1426
    PCSYMCRYPT_AES_CMAC_EXPANDED_KEY    pKey;
1427
1428
    SYMCRYPT_MAGIC_FIELD
1429
} SYMCRYPT_AES_CMAC_STATE, *PSYMCRYPT_AES_CMAC_STATE;
1430
typedef const SYMCRYPT_AES_CMAC_STATE * PCSYMCRYPT_AES_CMAC_STATE;
1431
1432
//
1433
// POLY1305
1434
//
1435
1436
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_POLY1305_STATE
1437
{
1438
    UINT32  r[4];       // R := \sum 2^{32*i} r[i]. R is already clamped.
1439
    UINT32  s[4];       // S := \sum 2^{32*i} s[i]
1440
    UINT32  a[5];       // Accumulator := sum 2^{32*i} a[i], a[4] <= approx 8
1441
    SIZE_T  bytesInBuffer;
1442
    BYTE    buf[16];    // Partial block buffer
1443
1444
    SYMCRYPT_MAGIC_FIELD
1445
} SYMCRYPT_POLY1305_STATE, *PSYMCRYPT_POLY1305_STATE;
1446
1447
//
1448
// XTS-AES
1449
//
1450
1451
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_XTS_AES_EXPANDED_KEY
1452
{
1453
    SYMCRYPT_AES_EXPANDED_KEY   key1;
1454
    SYMCRYPT_AES_EXPANDED_KEY   key2;
1455
} SYMCRYPT_XTS_AES_EXPANDED_KEY, *PSYMCRYPT_XTS_AES_EXPANDED_KEY;
1456
typedef const SYMCRYPT_XTS_AES_EXPANDED_KEY * PCSYMCRYPT_XTS_AES_EXPANDED_KEY;
1457
1458
1459
//-----------------------------------------------------------------
1460
//     Mac description table
1461
// Below are the typedefs for the Mac description table type
1462
// Callers can use this to define Mac algorithm they want to use
1463
//
1464
1465
#define SYMCRYPT_MAC_MAX_RESULT_SIZE    SYMCRYPT_HMAC_SHA512_RESULT_SIZE
1466
1467
typedef union _SYMCRYPT_MAC_STATE
1468
{
1469
    SYMCRYPT_HMAC_MD5_STATE         md5State;
1470
    SYMCRYPT_HMAC_SHA1_STATE        sha1State;
1471
    SYMCRYPT_HMAC_SHA256_STATE      sha256State;
1472
    SYMCRYPT_HMAC_SHA384_STATE      sha384State;
1473
    SYMCRYPT_HMAC_SHA512_STATE      sha512State;
1474
    SYMCRYPT_HMAC_SHA3_256_STATE    sha3_256State;
1475
    SYMCRYPT_HMAC_SHA3_384_STATE    sha3_384State;
1476
    SYMCRYPT_HMAC_SHA3_512_STATE    sha3_512State;
1477
    SYMCRYPT_AES_CMAC_STATE         aescmacState;
1478
    SYMCRYPT_KMAC128_STATE          kmac128State;
1479
    SYMCRYPT_KMAC256_STATE          kmac256State;
1480
} SYMCRYPT_MAC_STATE, *PSYMCRYPT_MAC_STATE;
1481
typedef const SYMCRYPT_MAC_STATE *PCSYMCRYPT_MAC_STATE;
1482
1483
typedef union _SYMCRYPT_MAC_EXPANDED_KEY
1484
{
1485
    SYMCRYPT_HMAC_MD5_EXPANDED_KEY      md5Key;
1486
    SYMCRYPT_HMAC_SHA1_EXPANDED_KEY     sha1Key;
1487
    SYMCRYPT_HMAC_SHA256_EXPANDED_KEY   sha256Key;
1488
    SYMCRYPT_HMAC_SHA384_EXPANDED_KEY   sha384Key;
1489
    SYMCRYPT_HMAC_SHA512_EXPANDED_KEY   sha512Key;
1490
    SYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY sha3_256Key;
1491
    SYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY sha3_384Key;
1492
    SYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY sha3_512Key;
1493
    SYMCRYPT_AES_CMAC_EXPANDED_KEY      aescmacKey;
1494
    SYMCRYPT_KMAC128_EXPANDED_KEY       kmac128Key;
1495
    SYMCRYPT_KMAC256_EXPANDED_KEY       kmac256Key;
1496
} SYMCRYPT_MAC_EXPANDED_KEY, *PSYMCRYPT_MAC_EXPANDED_KEY;
1497
typedef const SYMCRYPT_MAC_EXPANDED_KEY *PCSYMCRYPT_MAC_EXPANDED_KEY;
1498
1499
typedef SYMCRYPT_ERROR (SYMCRYPT_CALL * PSYMCRYPT_MAC_EXPAND_KEY)
1500
                                        ( PVOID pExpandedKey, PCBYTE pbKey, SIZE_T cbKey );
1501
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_INIT)     ( PVOID pState,  PCVOID pExpandedKey );
1502
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_APPEND)( PVOID pState, PCBYTE pbData, SIZE_T cbData );
1503
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_RESULT)  ( PVOID pState, PVOID pbResult );
1504
typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_RESULT_EX)  ( PVOID pState, PVOID pbResult, SIZE_T cbResult );
1505
1506
typedef struct _SYMCRYPT_MAC
1507
{
1508
    PSYMCRYPT_MAC_EXPAND_KEY    expandKeyFunc;
1509
    PSYMCRYPT_MAC_INIT          initFunc;
1510
    PSYMCRYPT_MAC_APPEND        appendFunc;
1511
    PSYMCRYPT_MAC_RESULT        resultFunc;
1512
    SIZE_T                      expandedKeySize;
1513
    SIZE_T                      stateSize;
1514
    SIZE_T                      resultSize;
1515
    const PCSYMCRYPT_HASH     * ppHashAlgorithm;            // NULL for MACs not based on hashes
1516
    UINT32                      outerChainingStateOffset;   // Offset into expanded key of outer chaining state; 0 for non-HMAC algorithms
1517
} SYMCRYPT_MAC, *PSYMCRYPT_MAC;
1518
typedef const SYMCRYPT_MAC  *PCSYMCRYPT_MAC;
1519
1520
1521
1522
//
1523
// 3DES
1524
//
1525
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_3DES_EXPANDED_KEY {
1526
    UINT32  roundKey[3][16][2];     // 3 keys, 16 rounds, 2 UINT32s/round
1527
    SYMCRYPT_MAGIC_FIELD
1528
} SYMCRYPT_3DES_EXPANDED_KEY, *PSYMCRYPT_3DES_EXPANDED_KEY;
1529
typedef const SYMCRYPT_3DES_EXPANDED_KEY * PCSYMCRYPT_3DES_EXPANDED_KEY;
1530
1531
//
1532
// DES
1533
//
1534
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_DES_EXPANDED_KEY {
1535
    SYMCRYPT_3DES_EXPANDED_KEY threeDes;
1536
} SYMCRYPT_DES_EXPANDED_KEY, *PSYMCRYPT_DES_EXPANDED_KEY;
1537
typedef const SYMCRYPT_DES_EXPANDED_KEY * PCSYMCRYPT_DES_EXPANDED_KEY;
1538
1539
//
1540
// DESX
1541
//
1542
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_DESX_EXPANDED_KEY {
1543
    SYMCRYPT_DES_EXPANDED_KEY   desKey;
1544
    BYTE                        inputWhitening[8];
1545
    BYTE                        outputWhitening[8];
1546
} SYMCRYPT_DESX_EXPANDED_KEY, *PSYMCRYPT_DESX_EXPANDED_KEY;
1547
typedef const SYMCRYPT_DESX_EXPANDED_KEY * PCSYMCRYPT_DESX_EXPANDED_KEY;
1548
1549
//
1550
// RC2
1551
//
1552
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_RC2_EXPANDED_KEY {
1553
    UINT16  K[64];
1554
    SYMCRYPT_MAGIC_FIELD
1555
} SYMCRYPT_RC2_EXPANDED_KEY, *PSYMCRYPT_RC2_EXPANDED_KEY;
1556
typedef const SYMCRYPT_RC2_EXPANDED_KEY * PCSYMCRYPT_RC2_EXPANDED_KEY;
1557
1558
1559
//
1560
// CCM states for incremental computations
1561
//
1562
0
#define SYMCRYPT_CCM_BLOCK_SIZE (16)
1563
1564
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_CCM_STATE {
1565
                                                    PCSYMCRYPT_BLOCKCIPHER  pBlockCipher;
1566
                                                    PCVOID                  pExpandedKey;
1567
                                                    UINT64                  cbData;                                     // exact length of data
1568
                                                    SIZE_T                  cbTag;
1569
                                                    SIZE_T                  cbNonce;
1570
                                                    SIZE_T                  cbCounter;                                  // # bytes in counter field
1571
                                                    UINT64                  bytesProcessed;                             // data bytes processed so far
1572
    _Field_range_( 0, SYMCRYPT_CCM_BLOCK_SIZE-1 )   SIZE_T                  bytesInMacBlock;
1573
                                                    SYMCRYPT_ALIGN BYTE     counterBlock[SYMCRYPT_CCM_BLOCK_SIZE];      // Current counter block value
1574
                                                    SYMCRYPT_ALIGN BYTE     macBlock[SYMCRYPT_CCM_BLOCK_SIZE];          // Current state of the CBC-MAC part of CCM
1575
                                                    SYMCRYPT_ALIGN BYTE     keystreamBlock[SYMCRYPT_CCM_BLOCK_SIZE];    // Remaining key stream if partial block has been processed
1576
                                                    SYMCRYPT_MAGIC_FIELD
1577
} SYMCRYPT_CCM_STATE, *PSYMCRYPT_CCM_STATE;
1578
1579
1580
//
1581
// GHash & GCM
1582
//
1583
1584
typedef union _SYMCRYPT_GCM_SUPPORTED_BLOCKCIPHER_KEYS
1585
{
1586
    SYMCRYPT_AES_EXPANDED_KEY aes;
1587
} SYMCRYPT_GCM_SUPPORTED_BLOCKCIPHER_KEYS;
1588
1589
#define SYMCRYPT_GCM_BLOCKCIPHER_KEY_SIZE sizeof( union _SYMCRYPT_GCM_SUPPORTED_BLOCKCIPHER_KEYS )
1590
1591
0
#define SYMCRYPT_GF128_FIELD_SIZE   (128)
1592
0
#define SYMCRYPT_GF128_BLOCK_SIZE   (16)        // # bytes in a field element/block
1593
0
#define SYMCRYPT_GCM_BLOCK_SIZE     (16)
1594
0
#define SYMCRYPT_GCM_MAX_KEY_SIZE   (32)
1595
1596
1597
0
#define SYMCRYPT_GCM_MAX_DATA_SIZE           (((UINT64)1 << 36) - 32)
1598
1599
0
#define SYMCRYPT_GCM_BLOCK_MOD_MASK      (SYMCRYPT_GCM_BLOCK_SIZE - 1)
1600
0
#define SYMCRYPT_GCM_BLOCK_ROUND_MASK    (~SYMCRYPT_GCM_BLOCK_MOD_MASK)
1601
1602
#if SYMCRYPT_CPU_X86
1603
    //
1604
    // x86 needs extra alignment of the GHASH expanded key to support
1605
    // aligned (fast) XMM access. AMD64 has enough natural alignment to
1606
    // achieve this.
1607
    //
1608
    #define SYMCRYPT_GHASH_EXTRA_KEY_ALIGNMENT
1609
#endif
1610
1611
#define SYMCRYPT_GHASH_ALLOW_XMM    (SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64)
1612
#define SYMCRYPT_GHASH_ALLOW_NEON   (SYMCRYPT_CPU_ARM | SYMCRYPT_CPU_ARM64)
1613
1614
1615
#if SYMCRYPT_CPU_ARM
1616
#include <arm_neon.h>
1617
#if SYMCRYPT_GNUC
1618
    #define __n128 uint32x4_t
1619
    #define __n64 uint64x1_t
1620
#endif
1621
1622
#elif SYMCRYPT_CPU_ARM64
1623
1624
    #if SYMCRYPT_MS_VC
1625
        #include <arm64_neon.h>
1626
1627
        // See section 6.7.8 of the C standard for details on this initializer usage.
1628
        #define SYMCRYPT_SET_N128_U64(d0, d1) \
1629
            ((__n128) {.n128_u64 = {d0, d1}})
1630
        #define SYMCRYPT_SET_N64_U64(d0) \
1631
            ((__n64) {.n64_u64 = {d0}})
1632
        #define SYMCRYPT_SET_N128_U8(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15) \
1633
            ((__n128) {.n128_u8 = {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15}})
1634
    #elif SYMCRYPT_GNUC
1635
        #include <arm_neon.h>
1636
1637
        #define __n128 uint8x16_t
1638
        #define __n64 uint8x8_t
1639
1640
        #define SYMCRYPT_SET_N128_U64(d0, d1) \
1641
            ((__n128) ((uint64x2_t) {d0, d1}))
1642
        #define SYMCRYPT_SET_N64_U64(d0) \
1643
            ((__n64) ((uint64x1_t) {d0}))
1644
        #define SYMCRYPT_SET_N128_U8(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15) \
1645
            ((__n128) ((uint8x16_t) {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15}))
1646
1647
        #define vmullq_p64( a, b )      ((__n128) vmull_p64(vgetq_lane_p64((poly64x2_t)a, 0), vgetq_lane_p64((poly64x2_t)b, 0)))
1648
        #define vmull_p64( a, b )       ((__n128) vmull_p64( (poly64_t)a, (poly64_t)b ))
1649
        #define vmull_high_p64( a, b )  ((__n128) vmull_high_p64( (poly64x2_t)a, (poly64x2_t)b ))
1650
1651
        typedef uint64_t ULONG64;
1652
    #endif
1653
1654
#endif
1655
1656
//
1657
// All platforms use the same in-memory representation:
1658
// elements of GF(2^128) stored as two 64-bit integers which are best
1659
// interpreted as a single 128-bit integer, least significant half first.
1660
// Note: the actual GF(2^128) bit order is reversed in the standard
1661
// for some reason; the
1662
// polynomial \sum b_i x^i is represented by integer \sum b_i 2^{127-i})
1663
// On x86/amd64 the same in-memory byte structure is also accessed as an
1664
// __m128i, which works as both the UINT64s, UINT32s, and the __m128i use
1665
// LSBfirst convention.
1666
//
1667
typedef SYMCRYPT_ALIGN_UNION _SYMCRYPT_GF128_ELEMENT {
1668
    UINT64 ull[2];
1669
#if SYMCRYPT_GHASH_ALLOW_XMM
1670
    //
1671
    // The XMM code accesses this both as UINT32[] and __m128i
1672
    // This is safe as XMM code only runs on little endian machines so the
1673
    // ordering is known.
1674
    //
1675
    __m128i     m128i;
1676
    UINT32      ul[4];
1677
#endif
1678
#if SYMCRYPT_GHASH_ALLOW_NEON
1679
    __n128      n128;
1680
    UINT32      ul[4];
1681
#endif
1682
} SYMCRYPT_GF128_ELEMENT, *PSYMCRYPT_GF128_ELEMENT;
1683
typedef const SYMCRYPT_GF128_ELEMENT * PCSYMCRYPT_GF128_ELEMENT;
1684
1685
1686
1687
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_GHASH_EXPANDED_KEY {
1688
#if defined( SYMCRYPT_GHASH_EXTRA_KEY_ALIGNMENT )
1689
    UINT32  tableOffset;
1690
    BYTE    tableSpace[ (SYMCRYPT_GF128_FIELD_SIZE + 1) * sizeof( SYMCRYPT_GF128_ELEMENT ) ];
1691
#else
1692
    SYMCRYPT_GF128_ELEMENT  table[ SYMCRYPT_GF128_FIELD_SIZE ];
1693
#endif
1694
} SYMCRYPT_GHASH_EXPANDED_KEY, *PSYMCRYPT_GHASH_EXPANDED_KEY;
1695
typedef const SYMCRYPT_GHASH_EXPANDED_KEY * PCSYMCRYPT_GHASH_EXPANDED_KEY;
1696
1697
1698
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_GCM_EXPANDED_KEY {
1699
    SYMCRYPT_GHASH_EXPANDED_KEY             ghashKey;
1700
    PCSYMCRYPT_BLOCKCIPHER                  pBlockCipher;
1701
    SYMCRYPT_GCM_SUPPORTED_BLOCKCIPHER_KEYS blockcipherKey;
1702
    SIZE_T                                  cbKey;
1703
    BYTE                                    abKey[SYMCRYPT_GCM_MAX_KEY_SIZE];
1704
    SYMCRYPT_MAGIC_FIELD
1705
} SYMCRYPT_GCM_EXPANDED_KEY, * PSYMCRYPT_GCM_EXPANDED_KEY;
1706
typedef const SYMCRYPT_GCM_EXPANDED_KEY * PCSYMCRYPT_GCM_EXPANDED_KEY;
1707
1708
1709
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_GCM_STATE {
1710
                                                    PCSYMCRYPT_GCM_EXPANDED_KEY pKey;
1711
                                                    UINT64                      cbData;         // Number of data bytes
1712
                                                    UINT64                      cbAuthData;     // Number of AAD bytes
1713
    _Field_range_( 0, SYMCRYPT_GCM_BLOCK_SIZE-1 )   SIZE_T                      bytesInMacBlock;
1714
                                                    SYMCRYPT_GF128_ELEMENT      ghashState;
1715
                                                    SYMCRYPT_ALIGN BYTE         counterBlock[SYMCRYPT_GCM_BLOCK_SIZE];
1716
                                                    SYMCRYPT_ALIGN BYTE         macBlock[SYMCRYPT_GCM_BLOCK_SIZE];
1717
                                                    SYMCRYPT_ALIGN BYTE         keystreamBlock[SYMCRYPT_GCM_BLOCK_SIZE];
1718
                                                    SYMCRYPT_MAGIC_FIELD
1719
} SYMCRYPT_GCM_STATE, * PSYMCRYPT_GCM_STATE;
1720
typedef const SYMCRYPT_GCM_STATE * PCSYMCRYPT_GCM_STATE;
1721
1722
1723
//
1724
// Block ciphers
1725
//
1726
0
#define SYMCRYPT_MAX_BLOCK_SIZE  (32)        // max block length of a block cipher.
1727
1728
typedef SYMCRYPT_ERROR( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_EXPAND_KEY )
1729
(PVOID pExpandedKey, PCBYTE pbKey, SIZE_T cbKey);
1730
typedef VOID( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_CRYPT )         (PCVOID pExpandedKey, PCBYTE pbSrc, PBYTE pbDst);
1731
typedef VOID( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_CRYPT_ECB )     (PCVOID pExpandedKey, PCBYTE pbSrc, PBYTE pbDst, SIZE_T cbData);
1732
typedef VOID( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE )    (PCVOID pExpandedKey, PBYTE pbChainingValue, PCBYTE pbSrc, PBYTE pbDst, SIZE_T cbData);
1733
typedef VOID( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_MAC_MODE )      (PCVOID pExpandedKey, PBYTE pbChainingValue, PCBYTE pbSrc, SIZE_T cbData);
1734
typedef VOID( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_AEADPART_MODE ) (PVOID pState, PCBYTE pbSrc, PBYTE pbDst, SIZE_T cbData);
1735
1736
struct _SYMCRYPT_BLOCKCIPHER {
1737
                                                PSYMCRYPT_BLOCKCIPHER_EXPAND_KEY    expandKeyFunc;      // mandatory
1738
                                                PSYMCRYPT_BLOCKCIPHER_CRYPT         encryptFunc;        // mandatory
1739
                                                PSYMCRYPT_BLOCKCIPHER_CRYPT         decryptFunc;        // mandatory
1740
                                                PSYMCRYPT_BLOCKCIPHER_CRYPT_ECB     ecbEncryptFunc;     // NULL if no optimized version available
1741
                                                PSYMCRYPT_BLOCKCIPHER_CRYPT_ECB     ecbDecryptFunc;     // NULL if no optimized version available
1742
                                                PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE    cbcEncryptFunc;     // NULL if no optimized version available
1743
                                                PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE    cbcDecryptFunc;     // NULL if no optimized version available
1744
                                                PSYMCRYPT_BLOCKCIPHER_MAC_MODE      cbcMacFunc;         // NULL if no optimized version available
1745
                                                PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE    ctrMsb64Func;       // NULL if no optimized version available
1746
                                                PSYMCRYPT_BLOCKCIPHER_AEADPART_MODE gcmEncryptPartFunc; // NULL if no optimized version available
1747
                                                PSYMCRYPT_BLOCKCIPHER_AEADPART_MODE gcmDecryptPartFunc; // NULL if no optimized version available
1748
    _Field_range_( 1, SYMCRYPT_MAX_BLOCK_SIZE ) SIZE_T                              blockSize;          // = SYMCRYPT_XXX_BLOCK_SIZE, power of 2, 1 <= value <= 32.
1749
                                                SIZE_T                              expandedKeySize;    // = sizeof( SYMCRYPT_XXX_EXPANDED_KEY )
1750
};
1751
1752
1753
1754
//
1755
// Session structs
1756
//
1757
1758
#define SYMCRYPT_FLAG_SESSION_ENCRYPT       (0x1)
1759
1760
//
1761
// SYMCRYPT_SESSION tracks the Nonces being used in a session. It is used differently depending on
1762
// whether the session is an Encryption session or a Decryption session.
1763
//
1764
// In Encryption sessions, SYMCRYPT_SESSION tracks the Nonce which was used in the most recent
1765
// attempted encryption in the session.
1766
// messageNumber is atomically incremented by each encryption call, and the encryption method uses
1767
// the messageNumber value that is the _result_ of the increment.
1768
//
1769
// In Decryption sessions, SYMCRYPT_SESSION tracks the most recently received Nonces in a series of
1770
// successful decryptions. Nonces used in unsuccessful decryption calls do not update SYMCRYPT_SESSION.
1771
// Information is tracked such that the decryption function can detect repeated Nonce values and
1772
// fail decryption in this case. In order for this to work the message numbers that are provided
1773
// to decrypt calls must be somewhat ordered. Provided message numbers may be arbitrarily far ahead
1774
// of previously successfully decrypted message numbers, but may only be up to 63 behind the highest
1775
// message number successfully decrypted so far.
1776
// messageNumber normally represents the highest message number used in a successful decryption in
1777
// this session. (The exception is at initialization, where messageNumber is initialized to 64
1778
// without the corresponding 0th bit in the replayMask being set - this initial state represents
1779
// there have been no successful decryptions yet, and that the earliest messageNumber that can be
1780
// successfully received is 1)
1781
// replayMask represents whether a window of 64 message numbers up to messageNumber have already been
1782
// successfully used;
1783
// bit n of replayMask (from n=0 to n=63) represents message number = (messageNumber-n), 0 means not
1784
// yet used, and 1 means already used in a successful decryption call
1785
//
1786
1787
#if SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM64
1788
#define SYMCRYPT_USE_CAS128 (1)
1789
1790
// For CompareAndSwap128 method, SYMCRYPT_SESSION must be aligned to 16B
1791
#define SYMCRYPT_ALIGN_SESSION SYMCRYPT_ALIGN_TYPE_AT(struct, 16)
1792
#else
1793
#define SYMCRYPT_USE_CAS128 (0)
1794
1795
// For method with only 64-bit atomics, SYMCRYPT_SESSION must be aligned to 8B
1796
#define SYMCRYPT_ALIGN_SESSION SYMCRYPT_ALIGN_TYPE_AT(struct, 8)
1797
#endif
1798
1799
// Nested struct used within SYMCRYPT_SESSION
1800
typedef SYMCRYPT_ALIGN_SESSION _SYMCRYPT_SESSION_REPLAY_STATE {
1801
    UINT64  replayMask;
1802
    // 64 bit mask representing message numbers previously successfully decrypted up to 63
1803
    // before the most recent message number.
1804
1805
    UINT64  messageNumber;
1806
    // the last 8 bytes of the Nonce (MSB-first)
1807
} SYMCRYPT_SESSION_REPLAY_STATE, * PSYMCRYPT_SESSION_REPLAY_STATE;
1808
typedef const SYMCRYPT_SESSION_REPLAY_STATE * PCSYMCRYPT_SESSION_REPLAY_STATE;
1809
1810
typedef SYMCRYPT_ALIGN_SESSION _SYMCRYPT_SESSION {
1811
    SYMCRYPT_SESSION_REPLAY_STATE replayState;
1812
    // nested replayState struct is to improve code clarity in SymCryptSessionDecryptUpdate*
1813
1814
    UINT32  senderId;
1815
    // the first 4 bytes of the Nonce (MSB-first)
1816
    // (set by the caller and constant for the lifetime of a session)
1817
1818
    UINT32  flags;
1819
    // SYMCRYPT_FLAG_SESSION_ENCRYPT indicates the struct is to be used for an encryption session,
1820
    // otherwise the struct is to be used for a decryption session
1821
1822
    PVOID   pMutex;
1823
    // Pointer to a fast single-process mutex object used to enable atomic update of replayMask and
1824
    // messageNumber in the absence of support for a 128b CAS operation
1825
} SYMCRYPT_SESSION, * PSYMCRYPT_SESSION;
1826
1827
#define SYMCRYPT_SESSION_MAX_MESSAGE_NUMBER (0xffffffff00000000ull)
1828
// We do not allow messageNumber to go above some maximum value (currently 2^64 - 2^32)
1829
// This gives us a large window to prevent many concurrent encryption threads from updating the
1830
// session such that the messageNumber overflows and the same IV is used in many encryptions
1831
// (i.e. we would only potentially get a spurious success using a repeated IV when there are
1832
// >2^32 concurrent threads!)
1833
1834
#if SYMCRYPT_USE_CAS128
1835
C_ASSERT(SYMCRYPT_FIELD_OFFSET(SYMCRYPT_SESSION, replayState.replayMask) == 0);
1836
C_ASSERT(SYMCRYPT_FIELD_OFFSET(SYMCRYPT_SESSION, replayState.messageNumber) == 8);
1837
// For CompareAndSwap128 method, replayMask and messageNumber must be tightly packed
1838
#endif
1839
1840
//
1841
// RC4
1842
//
1843
1844
//
1845
// Some CPUs like the S array type to be larger than BYTE. We abstract the data type
1846
// of the S array to accommodate such CPUs in future.
1847
//
1848
1849
typedef BYTE    SYMCRYPT_RC4_S_TYPE;
1850
1851
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_RC4_STATE {
1852
    SYMCRYPT_RC4_S_TYPE  S[256];
1853
    BYTE i;
1854
    BYTE j;
1855
    SYMCRYPT_MAGIC_FIELD
1856
} SYMCRYPT_RC4_STATE, *PSYMCRYPT_RC4_STATE;
1857
1858
//
1859
// ChaCha20
1860
//
1861
1862
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_CHACHA20_STATE {
1863
    UINT32      key[8];
1864
    UINT32      nonce[3];
1865
    UINT64      offset;                 // offset to use for next operation
1866
    BOOLEAN     keystreamBufferValid;   // keystream buffer matches offset value
1867
    BYTE        keystream[64];
1868
} SYMCRYPT_CHACHA20_STATE, *PSYMCRYPT_CHACHA20_STATE;
1869
1870
1871
//
1872
// AES_CTR_DRBG
1873
//
1874
1875
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_RNG_AES_STATE {
1876
    //
1877
    // Key and V value are in one array, to allow fast generation of both of them
1878
    // in a single call.
1879
    //
1880
    BYTE        keyAndV[32 + 16];
1881
    BYTE        previousBlock[16];
1882
    UINT64      requestCounter;         // called reseed_counter in SP 800-90
1883
    BOOLEAN     fips140_2Check;         // set if the FIPS 140-2 continuous self-test is required
1884
    SYMCRYPT_MAGIC_FIELD
1885
} SYMCRYPT_RNG_AES_STATE, * PSYMCRYPT_RNG_AES_STATE;
1886
1887
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_RNG_AES_FIPS140_2_STATE {
1888
    SYMCRYPT_RNG_AES_STATE  rng;
1889
} SYMCRYPT_RNG_AES_FIPS140_2_STATE, *PSYMCRYPT_RNG_AES_FIPS140_2_STATE;
1890
1891
1892
//
1893
// MARVIN32
1894
//
1895
1896
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MARVIN32_EXPANDED_SEED
1897
{
1898
    UINT32   s[2];
1899
    SYMCRYPT_MAGIC_FIELD
1900
} SYMCRYPT_MARVIN32_EXPANDED_SEED, *PSYMCRYPT_MARVIN32_EXPANDED_SEED;
1901
typedef const SYMCRYPT_MARVIN32_EXPANDED_SEED * PCSYMCRYPT_MARVIN32_EXPANDED_SEED;
1902
1903
1904
typedef SYMCRYPT_MARVIN32_EXPANDED_SEED SYMCRYPT_MARVIN32_CHAINING_STATE, * PSYMCRYPT_MARVIN32_CHAINING_STATE;
1905
1906
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MARVIN32_STATE
1907
{
1908
    SYMCRYPT_ALIGN  BYTE                                buffer[8];  // 4 bytes of data, 4 more bytes for final padding
1909
                    SYMCRYPT_MARVIN32_CHAINING_STATE    chain;      // chaining state
1910
                    PCSYMCRYPT_MARVIN32_EXPANDED_SEED   pSeed;      //
1911
                    UINT32                              dataLength; // length of the data processed so far, mod 2^32
1912
                    SYMCRYPT_MAGIC_FIELD
1913
} SYMCRYPT_MARVIN32_STATE, *PSYMCRYPT_MARVIN32_STATE;
1914
typedef const SYMCRYPT_MARVIN32_STATE *PCSYMCRYPT_MARVIN32_STATE;
1915
1916
1917
//
1918
// Export blob sizes
1919
//
1920
1921
0
#define SYMCRYPT_MD2_STATE_EXPORT_SIZE      (80)
1922
0
#define SYMCRYPT_MD4_STATE_EXPORT_SIZE      (116)
1923
0
#define SYMCRYPT_MD5_STATE_EXPORT_SIZE      (116)
1924
0
#define SYMCRYPT_SHA1_STATE_EXPORT_SIZE     (120)
1925
0
#define SYMCRYPT_SHA256_STATE_EXPORT_SIZE   (132)
1926
#define SYMCRYPT_SHA384_STATE_EXPORT_SIZE   (236)
1927
0
#define SYMCRYPT_SHA512_STATE_EXPORT_SIZE   (236)
1928
1929
0
#define SYMCRYPT_KECCAK_STATE_EXPORT_SIZE   (234)
1930
#define SYMCRYPT_SHA3_256_STATE_EXPORT_SIZE SYMCRYPT_KECCAK_STATE_EXPORT_SIZE
1931
#define SYMCRYPT_SHA3_384_STATE_EXPORT_SIZE SYMCRYPT_KECCAK_STATE_EXPORT_SIZE
1932
#define SYMCRYPT_SHA3_512_STATE_EXPORT_SIZE SYMCRYPT_KECCAK_STATE_EXPORT_SIZE
1933
1934
1935
//
1936
// KDF algorithms
1937
//
1938
1939
//
1940
// PBKDF2
1941
//
1942
1943
typedef struct _SYMCRYPT_PBKDF2_EXPANDED_KEY {
1944
    SYMCRYPT_MAC_EXPANDED_KEY   macKey;
1945
    PCSYMCRYPT_MAC              macAlg;
1946
} SYMCRYPT_PBKDF2_EXPANDED_KEY, *PSYMCRYPT_PBKDF2_EXPANDED_KEY;
1947
typedef const SYMCRYPT_PBKDF2_EXPANDED_KEY *PCSYMCRYPT_PBKDF2_EXPANDED_KEY;
1948
1949
//
1950
// SP 800-108
1951
//
1952
1953
typedef struct _SYMCRYPT_SP800_108_EXPANDED_KEY {
1954
    SYMCRYPT_MAC_EXPANDED_KEY   macKey;
1955
    PCSYMCRYPT_MAC              macAlg;
1956
} SYMCRYPT_SP800_108_EXPANDED_KEY, *PSYMCRYPT_SP800_108_EXPANDED_KEY;
1957
typedef const SYMCRYPT_SP800_108_EXPANDED_KEY *PCSYMCRYPT_SP800_108_EXPANDED_KEY;
1958
1959
//
1960
// TLS PRF 1.1
1961
//
1962
1963
typedef struct _SYMCRYPT_TLSPRF1_1_EXPANDED_KEY {
1964
    SYMCRYPT_HMAC_MD5_EXPANDED_KEY   macMd5Key;
1965
    SYMCRYPT_HMAC_SHA1_EXPANDED_KEY   macSha1Key;
1966
} SYMCRYPT_TLSPRF1_1_EXPANDED_KEY, *PSYMCRYPT_TLSPRF1_1_EXPANDED_KEY;
1967
typedef const SYMCRYPT_TLSPRF1_1_EXPANDED_KEY *PCSYMCRYPT_TLSPRF1_1_EXPANDED_KEY;
1968
1969
//
1970
// TLS PRF 1.2
1971
//
1972
1973
typedef struct _SYMCRYPT_TLSPRF1_2_EXPANDED_KEY {
1974
    SYMCRYPT_MAC_EXPANDED_KEY   macKey;
1975
    PCSYMCRYPT_MAC              macAlg;
1976
} SYMCRYPT_TLSPRF1_2_EXPANDED_KEY, *PSYMCRYPT_TLSPRF1_2_EXPANDED_KEY;
1977
typedef const SYMCRYPT_TLSPRF1_2_EXPANDED_KEY *PCSYMCRYPT_TLSPRF1_2_EXPANDED_KEY;
1978
1979
//
1980
// SSH-KDF
1981
//
1982
typedef struct _SYMCRYPT_SSHKDF_EXPANDED_KEY {
1983
    PCSYMCRYPT_HASH     pHashFunc;
1984
    SYMCRYPT_HASH_STATE hashState;
1985
} SYMCRYPT_SSHKDF_EXPANDED_KEY, *PSYMCRYPT_SSHKDF_EXPANDED_KEY;
1986
typedef const SYMCRYPT_SSHKDF_EXPANDED_KEY *PCSYMCRYPT_SSHKDF_EXPANDED_KEY;
1987
1988
//
1989
// SRTP-KDF
1990
//
1991
typedef struct _SYMCRYPT_SRTPKDF_EXPANDED_KEY {
1992
    SYMCRYPT_AES_EXPANDED_KEY     aesExpandedKey;
1993
} SYMCRYPT_SRTPKDF_EXPANDED_KEY, *PSYMCRYPT_SRTPKDF_EXPANDED_KEY;
1994
typedef const SYMCRYPT_SRTPKDF_EXPANDED_KEY *PCSYMCRYPT_SRTPKDF_EXPANDED_KEY;
1995
1996
//
1997
// HKDF
1998
//
1999
2000
typedef struct _SYMCRYPT_HKDF_EXPANDED_KEY {
2001
    SYMCRYPT_MAC_EXPANDED_KEY   macKey;
2002
    PCSYMCRYPT_MAC              macAlg;
2003
} SYMCRYPT_HKDF_EXPANDED_KEY, *PSYMCRYPT_HKDF_EXPANDED_KEY;
2004
typedef const SYMCRYPT_HKDF_EXPANDED_KEY *PCSYMCRYPT_HKDF_EXPANDED_KEY;
2005
2006
//
2007
// SSKDF
2008
//
2009
typedef struct _SYMCRYPT_SSKDF_MAC_EXPANDED_SALT {
2010
    SYMCRYPT_MAC_EXPANDED_KEY   macKey;
2011
    PCSYMCRYPT_MAC              macAlg;
2012
} SYMCRYPT_SSKDF_MAC_EXPANDED_SALT, *PSYMCRYPT_SSKDF_MAC_EXPANDED_SALT;
2013
typedef const SYMCRYPT_SSKDF_MAC_EXPANDED_SALT *PCSYMCRYPT_SSKDF_MAC_EXPANDED_SALT;
2014
2015
//
2016
// Digit & alignment sizes.
2017
//
2018
// WARNING: do not change these without updating all the optimized code,
2019
// including assembler code.
2020
// The FDEF_DIGIT_SIZE is the digit size used by the FDEF format.
2021
//
2022
#if SYMCRYPT_CPU_AMD64
2023
2024
43.2M
#define SYMCRYPT_FDEF_DIGIT_SIZE    64
2025
7.76k
#define SYMCRYPT_ASYM_ALIGN_VALUE   32
2026
2027
#elif SYMCRYPT_CPU_ARM64
2028
2029
#define SYMCRYPT_FDEF_DIGIT_SIZE    32
2030
#define SYMCRYPT_ASYM_ALIGN_VALUE   32
2031
2032
#else
2033
2034
#define SYMCRYPT_FDEF_DIGIT_SIZE    16
2035
#define SYMCRYPT_ASYM_ALIGN_VALUE   16              // We have some bugs when ASYM_ALIGN_VALUE > DIGIT_SIZE; need to fix them if we implement AVX2-based x86 code.
2036
2037
#endif
2038
2039
0
#define SYMCRYPT_ASYM_ALIGN_UP( _p ) ((PBYTE) ( ((UINT_PTR) (_p) + SYMCRYPT_ASYM_ALIGN_VALUE - 1) & ~(SYMCRYPT_ASYM_ALIGN_VALUE - 1 ) ) )
2040
2041
2042
//==============================================================================================
2043
// Object types for low-level API
2044
//
2045
// INT          integer in range 0..N for some N
2046
// DIVISOR      an integer > 0 that can be used to divide with.
2047
// MODULUS      a value M > 1 to use in modulo-M computations
2048
// MODELEMENT   An element in a modulo-M ring.
2049
// ECPOINT      A point on an elliptic curve.
2050
//
2051
// These objects are all aligned to SYMCRYPT_ASYM_ALIGN
2052
//
2053
#if SYMCRYPT_MS_VC
2054
#define SYMCRYPT_ASYM_ALIGN  __declspec(align(SYMCRYPT_ASYM_ALIGN_VALUE))
2055
#define SYMCRYPT_ASYM_ALIGN_STRUCT SYMCRYPT_ASYM_ALIGN struct
2056
#elif SYMCRYPT_GNUC
2057
#define SYMCRYPT_ASYM_ALIGN __attribute__((aligned(SYMCRYPT_ASYM_ALIGN_VALUE)))
2058
#define SYMCRYPT_ASYM_ALIGN_STRUCT struct SYMCRYPT_ASYM_ALIGN
2059
#else
2060
#error Unknown compiler
2061
#endif
2062
2063
SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_INT;
2064
typedef struct _SYMCRYPT_INT   SYMCRYPT_INT;
2065
typedef       SYMCRYPT_INT * PSYMCRYPT_INT;
2066
typedef const SYMCRYPT_INT * PCSYMCRYPT_INT;
2067
2068
SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_DIVISOR;
2069
typedef struct _SYMCRYPT_DIVISOR   SYMCRYPT_DIVISOR;
2070
typedef       SYMCRYPT_DIVISOR * PSYMCRYPT_DIVISOR;
2071
typedef const SYMCRYPT_DIVISOR * PCSYMCRYPT_DIVISOR;
2072
2073
SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_MODULUS;
2074
typedef struct _SYMCRYPT_MODULUS   SYMCRYPT_MODULUS;
2075
typedef       SYMCRYPT_MODULUS * PSYMCRYPT_MODULUS;
2076
typedef const SYMCRYPT_MODULUS * PCSYMCRYPT_MODULUS;
2077
2078
SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_MODELEMENT;
2079
typedef  struct _SYMCRYPT_MODELEMENT   SYMCRYPT_MODELEMENT;
2080
typedef       SYMCRYPT_MODELEMENT * PSYMCRYPT_MODELEMENT;
2081
typedef const SYMCRYPT_MODELEMENT * PCSYMCRYPT_MODELEMENT;
2082
2083
SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_ECPOINT;
2084
typedef struct _SYMCRYPT_ECPOINT   SYMCRYPT_ECPOINT;
2085
typedef       SYMCRYPT_ECPOINT * PSYMCRYPT_ECPOINT;
2086
typedef const SYMCRYPT_ECPOINT * PCSYMCRYPT_ECPOINT;
2087
2088
2089
//
2090
// Arithmetic formats
2091
//
2092
2093
#define SYMCRYPT_ANYSIZE    1       // used to mark arrays of arbitrary size
2094
2095
233k
#define SYMCRYPT_FDEF_DIGIT_BITS    (8*SYMCRYPT_FDEF_DIGIT_SIZE)
2096
58.3k
#define SYMCRYPT_FDEF_DIGITS_FROM_BITS( _bits )   ( \
2097
58.3k
                                                   ((_bits)/ SYMCRYPT_FDEF_DIGIT_BITS) + \
2098
58.3k
                                                   (( ((_bits) & (SYMCRYPT_FDEF_DIGIT_BITS-1)) + (SYMCRYPT_FDEF_DIGIT_BITS - 1) )/SYMCRYPT_FDEF_DIGIT_BITS) \
2099
58.3k
                                                  )
2100
2101
0
#define SYMCRYPT_BYTES_FROM_BITS(bits)          ( ( (bits) + 7 ) / 8 )
2102
2103
// The maximum number of bits in any integer value that the library supports. If the
2104
// caller's input exceed this bound then the the integer object will not be created.
2105
// The caller either must ensure the bound is not exceeded, or check for NULL before
2106
// using created SymCrypt objects.
2107
// The primary purpose of this limit is to avoid integer overlows in size computations.
2108
// Having a reasonable upper bound avoids all size overflows, even on 32-bit CPUs
2109
15.1k
#define SYMCRYPT_INT_MAX_BITS       ((UINT32)(1 << 20))
2110
2111
//
2112
// Upper bound for the number of digits: this MUST be enforced on runtime
2113
// on all Allocate, SizeOf, and Create calls which take as input a digit number.
2114
//
2115
// Using this upper bound and the SYMCRYPT_INT_MAX_BITS upper bound we can argue
2116
// that no integer overflow on 32-bit sizes can happen. Note that the computed upper
2117
// bounds are very loose and the actual values are much smaller.
2118
//
2119
42.9k
#define SYMCRYPT_FDEF_UPB_DIGITS    (SYMCRYPT_FDEF_DIGITS_FROM_BITS(SYMCRYPT_INT_MAX_BITS))
2120
2121
2122
2123
2124
//
2125
// All of the following SYMCRYPT_FDEF_SIZEOF_XXX_FROM_YYY computations for the four
2126
// main SymCrypt objects (INT, DIVISOR, MODULUS, MODELEMENT) return a value not
2127
// larger than 2^19 if the inputs _nDigits and _bits are not larger than
2128
// SYMCRYPT_FDEF_UPB_DIGITS and SYMCRYPT_INT_MAX_BITS respectively (For MODELEMENT this bound
2129
// is 2^17). The latter bounds must be enforced on runtime for all calculations taking as inputs
2130
// number of digits or bits.
2131
//
2132
// The 2^19 upper bound is derived from:
2133
//      - the maximum (byte) size of an "integer": 2^20 bits / 8 = 2^17 bytes
2134
//      - "sizeof" computations add up to less than 2^18 bytes ~ 262 Kb
2135
//      - the modulus object contains two "integers"
2136
//
2137
2138
//
2139
// Type fields contain the following:
2140
// lower 16 bits: offset into virtual table table (if any)
2141
// upper 16 bits: bits 16-23: 1-character object type. Bits 24-31: 1 char implementation type
2142
// The upper bits allow objects to be recognized in memory, making debugging easier.
2143
//
2144
2145
SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_INT {
2146
                                                    UINT32  type;
2147
    _Field_range_( 1, SYMCRYPT_FDEF_UPB_DIGITS )    UINT32  nDigits;    // digit size depends on run-time decisions...
2148
                                                    UINT32  cbSize;
2149
2150
    SYMCRYPT_MAGIC_FIELD
2151
    SYMCRYPT_ASYM_ALIGN union {
2152
        struct {
2153
            UINT32          uint32[SYMCRYPT_ANYSIZE];   // FDEF: array UINT32[nDigits * # uint32 per digit]
2154
        } fdef;
2155
    } ti;                   // we must have a name here. 'ti' stands for 'Type-Int', it helps catch type errors when type-casting macros are used.
2156
};
2157
2158
23.1M
#define SYMCRYPT_FDEF_INT_PUINT32( p )  (&(p)->ti.fdef.uint32[0])
2159
2160
2161
#define SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nDigits )    ((_nDigits) * SYMCRYPT_FDEF_DIGIT_SIZE + sizeof( SYMCRYPT_INT ) )
2162
#define SYMCRYPT_FDEF_SIZEOF_INT_FROM_BITS( _bits )         SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( SYMCRYPT_FDEF_DIGITS_FROM_BITS( _bits ))
2163
2164
SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_DIVISOR {
2165
                                                    UINT32  type;
2166
    _Field_range_( 1, SYMCRYPT_FDEF_UPB_DIGITS )    UINT32  nDigits;    // digit size depends on run-time decisions...
2167
                                                    UINT32  cbSize;
2168
2169
                                                    UINT32  nBits;      // # bits in divisor
2170
2171
    SYMCRYPT_MAGIC_FIELD
2172
    union{
2173
        struct {
2174
            UINT64                  W;              // approximate inverse of the divisor. Some implementations will use 64 bits, others 32 bits.
2175
        } fdef;
2176
    } td;
2177
    SYMCRYPT_INT            Int;                    // Having a full Int here uses more space, but allows any Divisor to still be used as an Int.
2178
    // This structure is directly followed by the Int extension
2179
};
2180
2181
0
#define SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_DIGITS( _nDigits ) ((_nDigits) * SYMCRYPT_FDEF_DIGIT_SIZE + sizeof( SYMCRYPT_DIVISOR ) )
2182
#define SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_BITS( _bits ) SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_DIGITS( SYMCRYPT_FDEF_DIGITS_FROM_BITS( _bits ))
2183
2184
SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_MODULUS {
2185
                                                    UINT32  type;
2186
    _Field_range_( 1, SYMCRYPT_FDEF_UPB_DIGITS )    UINT32  nDigits;        // digit size depends on run-time decisions...
2187
                                                    UINT32  cbSize;         // Size of modulus object
2188
2189
                                                    UINT32  flags;          // The flags the modulus was created with
2190
                                                    UINT32  cbModElement;   // Size of one modElement
2191
                                                    UINT64  inv64;          // -1/modulus mod 2^64 (always set but only to a useful value when the modulus is odd)
2192
2193
    SYMCRYPT_MAGIC_FIELD
2194
    union{
2195
        struct {
2196
            //UINT32          nUint32Used;    // # 32-bit words used in representing numbers. modulus < 2^{32*nUint32Used}.
2197
                                            // only values used are nDigits * uint32-per-digit or specific smaller values for optimized implementations
2198
            PCUINT32        Rsqr;           // R^2 mod modulus, in uint32 form, nUint32Used words. Stored after Divisor. R = 2^{32*nUint32Used}
2199
        } montgomery;
2200
        struct {
2201
            UINT32          k;              // modulus = 2^<bitsize of modelement> - k
2202
        } pseudoMersenne;
2203
    } tm;                                   // type specific data. Every Modulus can be used as a generic modulus, so no type-specific data for generic.
2204
2205
    SYMCRYPT_DIVISOR        Divisor;
2206
    // This structure is directly followed by:
2207
    //  The extensions of the Divisor object
2208
    // and after that:
2209
    // FDEF: Rsqr as an array of UINT32, size = nDigits * digitsize
2210
    // FDEF: negDivisor as an array of UINT32, size = nDigits * digitsize
2211
};
2212
2213
0
#define SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_DIGITS( _nDigits )    (sizeof( SYMCRYPT_MODULUS ) + SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_DIGITS( _nDigits ) + (2 * _nDigits * SYMCRYPT_FDEF_DIGIT_SIZE) )
2214
0
#define SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_BITS( _bits )         SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_DIGITS(SYMCRYPT_FDEF_DIGITS_FROM_BITS( _bits ))
2215
2216
SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_MODELEMENT {
2217
    // ModElements just store the information without any header. This union makes this well-defined, and allows easy access.
2218
    union{
2219
        UINT32    uint32[SYMCRYPT_ANYSIZE];
2220
    } d;
2221
};
2222
2223
946
#define SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nDigits )    ((_nDigits) * SYMCRYPT_FDEF_DIGIT_SIZE)
2224
946
#define SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_BITS( _bits )          SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( SYMCRYPT_FDEF_DIGITS_FROM_BITS( _bits ) )
2225
2226
//
2227
// Upper bound for scratch size computations for FDEF objects depending only on digits
2228
//
2229
// The following 14 scratch size computation macros are all of the form:
2230
//      Some SIZEOF macros + max( some other scratch macros )
2231
// and all depend on some number of digits. (Slight exceptions are
2232
// INT_TO_MODULUS and INT_PRIME_GEN but they can fit into the below
2233
// rationale.)
2234
//
2235
// One can see that the deepest recursion in these macros and the biggest
2236
// return value is for
2237
//      INT_PRIME_GEN -> INT_MILLER_RABIN -> MODEXP ->
2238
//      COMMON_MOD_OPERATIONS -> SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD
2239
//
2240
// Using the 2^19 (2^17) bound on the sizeof computations the biggest contribution on the above chain is for MODEXP:
2241
//      ((1 << SYMCRYPT_FDEF_MAX_WINDOW_MODEXP) + 2) * SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nModDigits )
2242
// which is bounded above by
2243
//      (2^6 + 2) * 2^17 < 2^24
2244
//
2245
// By doubling on each subsequent recursive call we get the conservative
2246
// upper bound for all scratch size computation macros of 2^26.
2247
//
2248
2249
1.89k
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits )  (16 * (_nDigits))   // unused currently, but this catches errors
2250
2251
0
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MUL( _nDigits )         (16 * (_nDigits))   // unused currently, but nonzero size catches errors
2252
2253
5.02M
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( _nSrcDigits, _nDivisorDigits )  ( (_nSrcDigits + 1) * SYMCRYPT_FDEF_DIGIT_SIZE )
2254
2255
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_EXTENDED_GCD( _nDigits ) ( \
2256
            4 * SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nDigits ) + \
2257
            SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( 2 * _nDigits ) + \
2258
            2 * SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_DIGITS( _nDigits ) + \
2259
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( 2 * _nDigits, _nDigits ), \
2260
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MUL( 2 * _nDigits ), \
2261
                 SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits ) )) )
2262
2263
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits ) \
2264
5.02M
            ( (2*(_nModDigits) * SYMCRYPT_FDEF_DIGIT_SIZE) + \
2265
5.02M
            SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( 2*(_nModDigits), _nModDigits )) // for mult: tmp product + divmod scratch
2266
2267
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_CRT_GENERATION( _nDigits ) ( \
2268
            2*SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nDigits ) + \
2269
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_EXTENDED_GCD( _nDigits ), \
2270
                 SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nDigits ) ))
2271
2272
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_CRT_SOLUTION( _nDigits ) ( \
2273
            SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nDigits ) + \
2274
            SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nDigits ) + \
2275
            SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( 2*_nDigits ) + \
2276
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nDigits ), \
2277
                 SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MUL( 2*_nDigits ) ))
2278
2279
0
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_MODULUS( _nDigits )  ( \
2280
0
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits ),\
2281
0
                (2*_nDigits+1) * SYMCRYPT_FDEF_DIGIT_SIZE + SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( 2*_nDigits + 1, nDigits )) )
2282
2283
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODINV( _nModDigits ) ( \
2284
            4 * SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nModDigits ) + \
2285
            3 * SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nModDigits ) + \
2286
            SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits ) )
2287
2288
#define SYMCRYPT_FDEF_MAX_WINDOW_MODEXP         (6)
2289
2290
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODEXP( _nModDigits ) ( \
2291
            ((1 << SYMCRYPT_FDEF_MAX_WINDOW_MODEXP) + 2) * SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nModDigits ) + \
2292
            SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits ) )
2293
2294
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_IS_POTENTIAL_PRIME( _nDigits )  (0)
2295
2296
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MILLER_RABIN( _nDigits ) ( \
2297
            SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_DIGITS(_nDigits) + \
2298
            3*SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS(_nDigits) + \
2299
            SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS(_nDigits) + \
2300
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_MODULUS(_nDigits), \
2301
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS(_nDigits), \
2302
                 SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODEXP( _nDigits ) )) )
2303
2304
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_IS_PRIME( _nDigits ) ( \
2305
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_IS_POTENTIAL_PRIME( _nDigits ), \
2306
                 SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MILLER_RABIN( _nDigits ) ))
2307
2308
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_PRIME_GEN( _nDigits ) ( \
2309
            SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS * SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_DIGITS( 1 ) + \
2310
            SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( 1 ) + \
2311
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( 1 ), \
2312
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( _nDigits, 1 ), \
2313
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nDigits ), \
2314
            SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_IS_POTENTIAL_PRIME( _nDigits ), \
2315
                 SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MILLER_RABIN( _nDigits ) )))))
2316
2317
//
2318
// Upper bound for SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODMULTIEXP
2319
//
2320
// _nBase and _nBitsExp are bounded by SYMCRYPT_MODMULTIEXP_MAX_NBASES = 8 and
2321
// SYMCRYPT_MODMULTIEXP_MAX_NBITSEXP = 2^20. Therefore the upper bound on this computation
2322
// is
2323
//      2^21 + 2^3*(2^6+4)*2^17 + 2^3*2^20*4 < 2^27
2324
//
2325
#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODMULTIEXP( _nModDigits, _nBases, _nBitsExp ) ( \
2326
    SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits ) + \
2327
    ((_nBases)*(1<<SYMCRYPT_FDEF_MAX_WINDOW_MODEXP) + 4)*SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nModDigits ) + \
2328
    (((_nBases)*(_nBitsExp)*sizeof(UINT32) + SYMCRYPT_ASYM_ALIGN_VALUE - 1) & ~(SYMCRYPT_ASYM_ALIGN_VALUE - 1)) )
2329
// Note: We need +4 mutliplied with SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS so that SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODMULTIEXP
2330
// is always at least 2 modelements bigger than SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODEXP (see modexp.c)
2331
2332
//
2333
// Support for masked operations
2334
2335
6.62k
#define SYMCRYPT_MASK32_SET             ((UINT32)-1)
2336
2.15M
#define SYMCRYPT_MASK32_NONZERO( _v )   ((UINT32)(((UINT64)0 - (_v)) >> 32))
2337
2.02M
#define SYMCRYPT_MASK32_ZERO( _v )      (~SYMCRYPT_MASK32_NONZERO( _v ))
2338
#define SYMCRYPT_MASK32_EQ( _a, _b )    (~SYMCRYPT_MASK32_NONZERO( (_a) ^ (_b) ))
2339
#define SYMCRYPT_MASK32_LT( _a, _b )    ((UINT32)( ((UINT64)(_a) - (_b)) >> 32 ))
2340
2341
2342
//
2343
// Dispatch definitions
2344
// When multiple formats are supported, this is where the information of the multiple formats is combined.
2345
//
2346
//  See the comments in SYMCRYPT_FDEF_SCRATCH_XXX regarding 32 bit overflow protection. All results
2347
//  are bounded above by 2^27.
2348
//
2349
2350
#define SYMCRYPT_INTERNAL_SIZEOF_INT_FROM_BITS( _bitsize )          SYMCRYPT_FDEF_SIZEOF_INT_FROM_BITS( _bitsize )
2351
#define SYMCRYPT_INTERNAL_SIZEOF_DIVISOR_FROM_BITS( _bitsize )      SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_BITS( _bitsize )
2352
0
#define SYMCRYPT_INTERNAL_SIZEOF_MODULUS_FROM_BITS( _bitsize )      SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_BITS( _bitsize )
2353
946
#define SYMCRYPT_INTERNAL_SIZEOF_MODELEMENT_FROM_BITS( _bitsize )   SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_BITS( _bitsize )
2354
2355
#define SYMCRYPT_INTERNAL_SIZEOF_RSAKEY_FROM_PARAMS( modBits, nPrimes, nPubExps ) SYMCRYPT_FDEF_SIZEOF_RSAKEY_FROM_PARAMS( modBits, nPrimes, nPubExps )
2356
// For now we don't need the pubExpBits so we drop them, but we might use them later.
2357
2358
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits )                      SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits )
2359
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_MUL( _nDigits )                             SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MUL( _nDigits )
2360
0
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_DIVMOD( _nSrcDigits, _nDivisorDigits )      SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( _nSrcDigits, _nDivisorDigits )
2361
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_EXTENDED_GCD( _nDigits )                        SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_EXTENDED_GCD( _nDigits )
2362
5.02M
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits )            SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits )
2363
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_CRT_GENERATION( _nDigits )                      SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_CRT_GENERATION( _nDigits )
2364
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_CRT_SOLUTION( _nDigits )                        SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_CRT_SOLUTION( _nDigits )
2365
0
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_TO_MODULUS( _nDigits )                      SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_MODULUS( _nDigits )
2366
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_MODINV( _nModDigits )                           SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODINV( _nModDigits )
2367
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_MODEXP( _nModDigits )                           SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODEXP( _nModDigits )
2368
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_IS_PRIME( _nDigits )                        SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_IS_PRIME( _nDigits )
2369
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_PRIME_GEN( _nDigits )                       SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_PRIME_GEN( _nDigits )
2370
2371
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_MODMULTIEXP( _nModDigits, _nBases, _nBitsExp )  SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODMULTIEXP( _nModDigits, _nBases, _nBitsExp )
2372
2373
//
2374
// Forward declarations for MlKemkey types
2375
//
2376
SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_MLKEMKEY;
2377
typedef struct _SYMCRYPT_MLKEMKEY SYMCRYPT_MLKEMKEY;
2378
typedef       SYMCRYPT_MLKEMKEY * PSYMCRYPT_MLKEMKEY;
2379
typedef const SYMCRYPT_MLKEMKEY * PCSYMCRYPT_MLKEMKEY;
2380
2381
//
2382
// RSA padding scratch definitions
2383
//
2384
// The maximum sizes of the state and the result for all hash algorithms are
2385
// sizeof(SYMCRYPT_HASH_STATE) and SYMCRYPT_HASH_MAX_RESULT_SIZE, both not bigger
2386
// 2^20. All the nBytes inputs are bounded by 2^17 (the maximum byte-size
2387
// of the RSA modulus).
2388
//
2389
// Thus a total upper bound on these results is 2^20.
2390
//
2391
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_RSA_OAEP( _hashAlgorithm, _nBytesOAEP ) ( SymCryptHashStateSize( _hashAlgorithm ) + \
2392
                                                                                      SymCryptHashResultSize( _hashAlgorithm ) + \
2393
                                                                                      2*(_nBytesOAEP - 1) )
2394
2395
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_RSA_PKCS1( _nBytesPKCS1 ) ( _nBytesPKCS1 )
2396
2397
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_RSA_PSS( _hashAlgorithm, _nBytesMessage, _nBytesPSS ) ( SymCryptHashStateSize( _hashAlgorithm ) + \
2398
                                                                                                    _nBytesMessage + \
2399
                                                                                                    3*(_nBytesPSS) + 5 )
2400
2401
//
2402
// RSAKEY Type
2403
//
2404
2405
#define SYMCRYPT_FDEF_SIZEOF_RSAKEY_FROM_PARAMS( modBits, nPrimes, nPubExps ) \
2406
    sizeof( SYMCRYPT_RSAKEY ) + \
2407
    (nPrimes + 1) * SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_BITS( modBits ) + \
2408
    nPrimes * SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_BITS( modBits ) + \
2409
    (nPrimes + 1) * nPubExps * SYMCRYPT_FDEF_SIZEOF_INT_FROM_BITS( modBits )
2410
// 1 modulus object per prime + 1 for the RSA modulus
2411
// 1 modelement for every crtInverse
2412
// 1 int per pubexp for each privexp +  1 int per prime*pubexp for each crtprivexp
2413
2414
0
#define SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES            (2)
2415
0
#define SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS           (1)
2416
2417
0
#define SYMCRYPT_RSAKEY_MIN_BITSIZE_MODULUS         (256)               // Some of our SCS code requires at least 32 bytes...
2418
0
#define SYMCRYPT_RSAKEY_MAX_BITSIZE_MODULUS         (1 << 16)           // Avoid any integer overflows in size calculations
2419
2420
// RSA FIPS self-tests require at least 496 bits to avoid fatal
2421
// Require caller to specify NO_FIPS for up to 1024 bits as running FIPS tests on too-small keys
2422
// does not make it FIPS certifiable and gives the wrong impression to callers
2423
0
#define SYMCRYPT_RSAKEY_FIPS_MIN_BITSIZE_MODULUS    (1024)      
2424
2425
0
#define SYMCRYPT_RSAKEY_MIN_BITSIZE_PRIME           (128)
2426
#define SYMCRYPT_RSAKEY_MAX_BITSIZE_PRIME           (SYMCRYPT_RSAKEY_MAX_BITSIZE_MODULUS / 2)
2427
2428
// Minimum allowable bit sizes for generated and imported parameters for
2429
// the RSA modulus and each prime.
2430
2431
typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_RSAKEY {
2432
                    UINT32              fAlgorithmInfo;     // Tracks which algorithms the key can be used in
2433
                                                            // Also tracks which per-key selftests have been performed on this key
2434
                                                            // A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_RSAKEY_*, and
2435
                                                            // SYMCRYPT_PCT_* values
2436
2437
                    UINT32              cbTotalSize;        // Total size of the rsa key
2438
                    BOOLEAN             hasPrivateKey;      // Set to true if there is private key information set
2439
2440
                    UINT32              nSetBitsOfModulus;  // Bits of modulus specified during creation
2441
2442
                    UINT32              nBitsOfModulus;     // Number of bits of the value of the modulus (not the object's size)
2443
                    UINT32              nDigitsOfModulus;   // Number of digits of the modulus object (always equal to SymCryptDigitsFromBits(nSetBitsOfModulus))
2444
2445
                    UINT32              nPubExp;            // Number of public exponents
2446
2447
                    UINT32              nPrimes;            // Number of primes, can be 0 if the object only supports public keys
2448
                    UINT32              nBitsOfPrimes[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];
2449
                                                            // Number of bits of the value of each prime (not the object's size)
2450
                    UINT32              nDigitsOfPrimes[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];
2451
                                                            // Number of digits of each prime object
2452
                    UINT32              nMaxDigitsOfPrimes; // Maximum number of digits in nDigitsOfPrimes
2453
2454
                    UINT64              au64PubExp[SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS];
2455
                    // SYMCRYPT_ASYM_ALIGN'ed buffers that point to memory allocated for each object
2456
                    PBYTE               pbPrimes[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];
2457
                    PBYTE               pbCrtInverses[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];
2458
                    PBYTE               pbPrivExps[SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS];
2459
                    PBYTE               pbCrtPrivExps[SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS * SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];
2460
2461
                    // SymCryptObjects
2462
                    PSYMCRYPT_MODULUS   pmModulus;          // The modulus N=p*q
2463
                    PSYMCRYPT_MODULUS   pmPrimes[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];
2464
                                                            // Pointers to the secret primes
2465
                    PSYMCRYPT_MODELEMENT peCrtInverses[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];
2466
                                                            // Pointers to the CRT inverses of the primes
2467
                    PSYMCRYPT_INT       piPrivExps[SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS];
2468
                                                            // Pointers to the corresponding private exponents
2469
                    PSYMCRYPT_INT       piCrtPrivExps[SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS * SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];
2470
                                                            // Pointers to the private exponents modulo each prime minus 1 (for CRT)
2471
2472
                    SYMCRYPT_MAGIC_FIELD
2473
                    // Followed by:
2474
                    // Modulus
2475
                    // Primes
2476
                    // CrtInverses
2477
                    // PrivExps
2478
                    // CrtPrivExps
2479
} SYMCRYPT_RSAKEY;
2480
typedef       SYMCRYPT_RSAKEY * PSYMCRYPT_RSAKEY;
2481
typedef const SYMCRYPT_RSAKEY * PCSYMCRYPT_RSAKEY;
2482
2483
//
2484
// The following definitions relating to trial divisoin are not needed by normal callers
2485
// but are used by the test program to measure performance of components.
2486
//
2487
2488
typedef struct _SYMCRYPT_TRIALDIVISION_PRIME {
2489
    UINT64  invMod2e64;         // Inverse of prime modulo 2^64
2490
    UINT64  compareLimit;       // floor( (2^{64}-1)/ prime )
2491
} SYMCRYPT_TRIALDIVISION_PRIME, *PSYMCRYPT_TRIALDIVISION_PRIME;
2492
typedef const SYMCRYPT_TRIALDIVISION_PRIME * PCSYMCRYPT_TRIALDIVISION_PRIME;
2493
//
2494
// This structure is used to test whether a UINT64 is a multiple of a (small) prime.
2495
// Let V be the input value, P the small prime, and W the inverse of P modulo 2^64.
2496
// If V = k*P then V * M mod 2^64 = V/P mod 2^64 = k.
2497
// This holds for k = 0, 1, ..., floor( (2^{64}-1)/p ).
2498
// If V is not a multiple of P then the result of the multiplication must be larger than that.
2499
//
2500
2501
typedef struct _SYMCRYPT_TRIALDIVISION_GROUP {
2502
    UINT32  nPrimes;       // # primes are in this group (use the next ones)
2503
    UINT32  factor[9];     // factors[i] = 2^{32*(i+1)} mod Prod where Prod = product of the primes
2504
                           // It is guaranteed that Prod <= (2^{32}-1)/9
2505
} SYMCRYPT_TRIALDIVISION_GROUP, *PSYMCRYPT_TRIALDIVISION_GROUP;
2506
typedef const SYMCRYPT_TRIALDIVISION_GROUP * PCSYMCRYPT_TRIALDIVISION_GROUP;
2507
2508
2509
typedef struct _SYMCRYPT_TRIALDIVISION_CONTEXT {
2510
    SIZE_T                          nBytesAlloc;
2511
    UINT32                          maxTrialPrime;
2512
    PSYMCRYPT_TRIALDIVISION_GROUP   pGroupList; // terminated with 0 record
2513
    PSYMCRYPT_TRIALDIVISION_PRIME   pPrimeList; // terminated with 0 record
2514
    PUINT32                         pPrimes;    // terminated with a 0.
2515
    SYMCRYPT_TRIALDIVISION_PRIME    Primes3_5_17[3];    // Structures for 3, 5 and 17 in that order
2516
} SYMCRYPT_TRIALDIVISION_CONTEXT, *PSYMCRYPT_TRIALDIVISION_CONTEXT;
2517
typedef const SYMCRYPT_TRIALDIVISION_CONTEXT * PCSYMCRYPT_TRIALDIVISION_CONTEXT;
2518
2519
UINT32
2520
SymCryptTestTrialdivisionMaxSmallPrime( PCSYMCRYPT_TRIALDIVISION_CONTEXT pContext );   // Expose small prime limit to help test code
2521
2522
//
2523
// DLGROUP type
2524
//
2525
2526
0
#define SYMCRYPT_DLGROUP_MIN_BITSIZE_P          (32)
2527
0
#define SYMCRYPT_DLGROUP_MIN_BITSIZE_Q          (31)  // Q must always be at least 1 bit shorter than P
2528
// Minimum allowable bit sizes for generated and imported parameters for both P and
2529
// Q primes.
2530
2531
typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_DLGROUP {
2532
    UINT32                  cbTotalSize;    // Total size of the dl group object
2533
    BOOLEAN                 fHasPrimeQ;     // Flag that specifies whether the object has a Q parameter
2534
2535
    UINT32                  nBitsOfP;       // Number of bits of the value of P (not the object's size)
2536
    UINT32                  cbPrimeP;       // Number of bytes of the value of P (not the object's size), equal to ceil(nBitsOfP/8)
2537
    UINT32                  nDigitsOfP;     // Number of digits of the object of prime P
2538
    UINT32                  nMaxBitsOfP;    // Maximum number of bits of the value of P
2539
2540
    UINT32                  nBitsOfQ;       // Number of bits of the value of Q (not the object's bits)
2541
    UINT32                  cbPrimeQ;       // Number of bytes of the value of Q (not the object's size), equal to ceil(nBitsOfQ/8)
2542
    UINT32                  nDigitsOfQ;     // Number of digits of the object of prime Q
2543
    UINT32                  nMaxBitsOfQ;    // Maximum number of bits of the value of Q
2544
2545
    BOOLEAN                 isSafePrimeGroup;   // Boolean indicating if this is a Safe Prime group
2546
    UINT32                  nMinBitsPriv;   // Minimum number of bits to be used in private keys for this group
2547
                                            // This only applies to named Safe Prime groups where this is related to the security strength
2548
                                            // i.e. this corresponds to 2s in SP800-56arev3 5.6.1.1.1 / 5.6.2.1.2
2549
    UINT32                  nDefaultBitsPriv;   // Default number of bits used in private keys for this group
2550
                                                // Normally equals nBitsOfQ, but may be further restricted (i.e. for named Safe Prime groups)
2551
                                                // i.e. this corresponds to a default value of N in SP800-56arev3 5.6.1.1.1 / 5.6.2.1.2
2552
2553
    UINT32                  nBitsOfSeed;    // Number of bits of the seed used for generation (seedlen in FIPS 186-3)
2554
    UINT32                  cbSeed;         // Number of bytes of the seed, equal to ceil(nBitsOfSeed/8)
2555
2556
    SYMCRYPT_DLGROUP_FIPS   eFipsStandard;  // Code specifying the FIPS standard used to create the keys. If 0 the group is unverified.
2557
2558
    PCSYMCRYPT_HASH         pHashAlgorithm; // Hash algorithm used for the generation of parameters
2559
    UINT32                  dwGenCounter;   // Number of iterations used for the generation of parameters
2560
    BYTE                    bIndexGenG;     // Index for the generation of generator G (FIPS 186-3) (Always 1 for now)
2561
2562
    PBYTE                   pbQ;            // SYMCRYPT_ASYM_ALIGN'ed buffer that points to the memory allocated for modulus Q
2563
2564
    PSYMCRYPT_MODULUS       pmP;            // Pointer to the prime P
2565
    PSYMCRYPT_MODULUS       pmQ;            // Pointer to the prime Q
2566
2567
    PSYMCRYPT_MODELEMENT    peG;            // Pointer to the generator G
2568
2569
    PBYTE                   pbSeed;         // Buffer that will hold the seed (this is padded at the end so that the entire structure
2570
                                            // has size a multiple of SYMCRYPT_ASYM_ALIGN_VALUE)
2571
2572
    SYMCRYPT_MAGIC_FIELD
2573
2574
    // P
2575
    // Q
2576
    // G
2577
    // Seed
2578
} SYMCRYPT_DLGROUP;
2579
typedef       SYMCRYPT_DLGROUP * PSYMCRYPT_DLGROUP;
2580
typedef const SYMCRYPT_DLGROUP * PCSYMCRYPT_DLGROUP;
2581
2582
//
2583
// DLKEY type
2584
//
2585
typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_DLKEY {
2586
                    UINT32                  fAlgorithmInfo; // Tracks which algorithms the key can be used in
2587
                                                            // Also tracks which per-key selftests have been performed on this key
2588
                                                            // A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_DLKEY_*, and
2589
                                                            // SYMCRYPT_PCT_* values
2590
2591
                    BOOLEAN                 fHasPrivateKey; // Set to true if there is a private key set
2592
                    BOOLEAN                 fPrivateModQ;   // Set to true if the private key is at most Q-1, otherwise it is at most P-2
2593
                    UINT32                  nBitsPriv;      // Number of bits used in private keys
2594
2595
                    PCSYMCRYPT_DLGROUP      pDlgroup;       // Handle to the group which created the key
2596
2597
                    PBYTE                   pbPrivate;      // SYMCRYPT_ASYM_ALIGN'ed buffer that points to the memory allocated for the private key
2598
2599
                    PSYMCRYPT_MODELEMENT    pePublicKey;    // Public key (modelement modulo P)
2600
                    PSYMCRYPT_INT           piPrivateKey;   // Private key (integer up to 2^nBitsPriv-1, Q-1 or P-2)
2601
2602
                    SYMCRYPT_MAGIC_FIELD
2603
2604
                    // PublicKey
2605
                    // PrivateKey                           // The size of this must always be the same as the size of P
2606
} SYMCRYPT_DLKEY;
2607
typedef       SYMCRYPT_DLKEY * PSYMCRYPT_DLKEY;
2608
typedef const SYMCRYPT_DLKEY * PCSYMCRYPT_DLKEY;
2609
2610
//
2611
// Elliptic Curve Function Types
2612
//
2613
2614
68.2k
#define SYMCRYPT_ECPOINT_FORMAT_MAX_LENGTH                      4   // Number of MODELEMENTs for the largest ECPOINT format
2615
2616
// Coordinate representations for ECPOINTs
2617
// NOTE: The value masked with 0xf gives you the number of coordinates
2618
typedef enum _SYMCRYPT_ECPOINT_COORDINATES {
2619
    SYMCRYPT_ECPOINT_COORDINATES_INVALID             = 0x00,   // Invalid point representation
2620
    SYMCRYPT_ECPOINT_COORDINATES_SINGLE              = 0x11,   // Representation with only X
2621
    SYMCRYPT_ECPOINT_COORDINATES_AFFINE              = 0x22,   // Affine representation (X,Y)
2622
    SYMCRYPT_ECPOINT_COORDINATES_PROJECTIVE          = 0x33,   // Three equally-sized values where the triple (X,Y,Z) represents the affine point (X/Z, Y/Z)
2623
    SYMCRYPT_ECPOINT_COORDINATES_JACOBIAN            = 0x43,   // Three equally-sized values where the triple (X,Y,Z) represents the affine point (X/Z^2, Y/Z^3)
2624
    SYMCRYPT_ECPOINT_COORDINATES_EXTENDED_PROJECTIVE = 0x54,   // Four equally-sized values where (X,Y,Z,T) represents the affine point (X/Z, Y/Z) with T=X*Y*Z
2625
    SYMCRYPT_ECPOINT_COORDINATES_SINGLE_PROJECTIVE   = 0x62,   // Two equally-sized values where (X,Z) represents the point (X/Z)
2626
} SYMCRYPT_ECPOINT_COORDINATES;
2627
2628
1.04M
#define SYMCRYPT_INTERNAL_NUMOF_COORDINATES( _eCoordinates )              ((_eCoordinates) & 0xf)
2629
2630
2631
//
2632
// Curve-type-dependent information
2633
//
2634
2635
// Short-Weierstrass
2636
2637
2.83k
#define SYMCRYPT_ECURVE_SW_DEF_WINDOW               (6)         // Default window size for the windowed methods
2638
2639
#define SYMCRYPT_ECURVE_SW_MAX_NPRECOMP_POINTS      (64)        // Maximum number of precomputed points
2640
2641
typedef struct _SYMCRYPT_ECURVE_INFO_PRECOMP {
2642
                    UINT32              window;         // Window size
2643
                    UINT32              nPrecompPoints; // Number of precomputed points
2644
                    UINT32              nRecodedDigits; // Number of recoded digits
2645
                    PSYMCRYPT_ECPOINT   poPrecompPoints[SYMCRYPT_ECURVE_SW_MAX_NPRECOMP_POINTS];
2646
                                                        // Table of pointers to precomputed powers of the distinguished point
2647
} SYMCRYPT_ECURVE_INFO_PRECOMP;
2648
2649
//
2650
//  ECURVE object
2651
//
2652
2653
946
#define SYMCRYPT_ECURVE_MIN_BITSIZE_FMOD        (32)
2654
946
#define SYMCRYPT_ECURVE_MIN_BITSIZE_GORD        (32)
2655
946
#define SYMCRYPT_ECURVE_MAX_COFACTOR_POWER      (8)
2656
// Minimum (maximum for cofactor) allowable bit sizes for imported
2657
// parameters for field modulus, group order of curve (and cofactor).
2658
2659
946
#define SYMCRYPT_INTERNAL_ECURVE_VERSION_LATEST                         1
2660
2661
typedef enum _SYMCRYPT_INTERNAL_ECURVE_TYPE {
2662
    SYMCRYPT_INTERNAL_ECURVE_TYPE_SHORT_WEIERSTRASS     = 1,
2663
    SYMCRYPT_INTERNAL_ECURVE_TYPE_TWISTED_EDWARDS       = 2,
2664
    SYMCRYPT_INTERNAL_ECURVE_TYPE_MONTGOMERY            = 3,
2665
    SYMCRYPT_INTERNAL_ECURVE_TYPE_SHORT_WEIERSTRASS_AM3 = 4,// This type is a specialization of Short-Weierstrass when A == -3
2666
                                                            // This condition is detected and used for all NIST prime curves
2667
} SYMCRYPT_INTERNAL_ECURVE_TYPE;
2668
2669
C_ASSERT((int)SYMCRYPT_INTERNAL_ECURVE_TYPE_SHORT_WEIERSTRASS   == (int)SYMCRYPT_ECURVE_TYPE_SHORT_WEIERSTRASS );
2670
C_ASSERT((int)SYMCRYPT_INTERNAL_ECURVE_TYPE_TWISTED_EDWARDS     == (int)SYMCRYPT_ECURVE_TYPE_TWISTED_EDWARDS );
2671
C_ASSERT((int)SYMCRYPT_INTERNAL_ECURVE_TYPE_MONTGOMERY          == (int)SYMCRYPT_ECURVE_TYPE_MONTGOMERY );
2672
2673
typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_ECURVE {
2674
                    UINT32                  version;        // Version #
2675
                    SYMCRYPT_INTERNAL_ECURVE_TYPE
2676
                                            type;           // Internal type of the curve
2677
                    SYMCRYPT_ECPOINT_COORDINATES
2678
                                            eCoordinates;   // Default representation of the EC points
2679
2680
                    UINT32                  FModBitsize;    // Bitsize of the field modulus
2681
                    UINT32                  FModDigits;     // Number of digits of the field modulus
2682
                    UINT32                  FModBytesize;   // Bytesize of the field modulus (specified in the curve parameters as cbFieldLength)
2683
2684
                    UINT32                  GOrdBitsize;    // Bitsize of the (sub)group order
2685
                    UINT32                  GOrdDigits;     // Number of digits of the (sub)group order
2686
                    UINT32                  GOrdBytesize;   // Bytesize of the (sub)group order (specified in the curve parameters as cbSubgroupOrder)
2687
2688
                    UINT32                  cbModElement;   // (Internal) bytesize of one mod element
2689
2690
                    UINT32                  cbAlloc;        // Bytesize of the total curve blob
2691
2692
                    UINT32                  cbScratchCommon;        // Size of scratch space for common ecurve operations
2693
                    UINT32                  cbScratchScalar;        // Size of constant scratch space for scalar ecurve operations (without the nPoints dependence)
2694
                    UINT32                  cbScratchScalarMulti;   // Dependence of scratch space for scalar ecurve operations from nPoints
2695
                    UINT32                  cbScratchGetSetValue;   // Size of scratch space for get set value ecpoint operations
2696
                    UINT32                  cbScratchEckey;         // Size of scratch space for eckey operations
2697
2698
                    UINT32                  coFactorPower;  // The cofactor of the curve will be equal to 2^coFactorPower
2699
2700
                    // Parameters V2 Extensions
2701
                    UINT32                  PrivateKeyDefaultFormat;
2702
                    UINT32                  HighBitRestrictionNumOfBits;
2703
                    UINT32                  HighBitRestrictionPosition;
2704
                    UINT32                  HighBitRestrictionValue;
2705
2706
                    union {
2707
2708
                        SYMCRYPT_ECURVE_INFO_PRECOMP sw;    // Info for short Weierstrass curves (only the precomputation parameters are needed now)
2709
2710
                    } info;                                 // Precomputed information related to each curve
2711
2712
                    PSYMCRYPT_MODULUS       FMod;           // Field modulus
2713
                    PSYMCRYPT_MODULUS       GOrd;           // Order of the subgroup
2714
2715
                    PSYMCRYPT_MODELEMENT    A;              // Parameter A
2716
                    PSYMCRYPT_MODELEMENT    B;              // Parameter B
2717
                    PSYMCRYPT_ECPOINT       G;              // Distinguished point (generator of the subgroup)
2718
                    PSYMCRYPT_INT           H;              // Cofactor of the curve
2719
2720
                    SYMCRYPT_MAGIC_FIELD
2721
2722
                    // FMod
2723
                    // A
2724
                    // B
2725
                    // GOrd
2726
                    // H
2727
                    // G
2728
} SYMCRYPT_ECURVE;
2729
typedef       SYMCRYPT_ECURVE * PSYMCRYPT_ECURVE;
2730
typedef const SYMCRYPT_ECURVE * PCSYMCRYPT_ECURVE;
2731
2732
3.38M
#define SYMCRYPT_INTERNAL_ECPOINT_COORDINATE_OFFSET( _pCurve, _ord )        ( sizeof(SYMCRYPT_ECPOINT) + (_ord) * (_pCurve)->cbModElement )
2733
3.37M
#define SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( _ord, _pCurve, _pEcpoint )    (PSYMCRYPT_MODELEMENT)( (PBYTE)(_pEcpoint) + SYMCRYPT_INTERNAL_ECPOINT_COORDINATE_OFFSET( (_pCurve), _ord ) )
2734
2735
// Convenience macros to make adding internal specializations easier
2736
#define SYMCRYPT_CURVE_IS_SHORT_WEIERSTRASS_TYPE( _pCurve ) \
2737
    ( _pCurve->type == SYMCRYPT_INTERNAL_ECURVE_TYPE_SHORT_WEIERSTRASS || \
2738
      _pCurve->type == SYMCRYPT_INTERNAL_ECURVE_TYPE_SHORT_WEIERSTRASS_AM3 )
2739
2740
#define SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE( _pCurve ) \
2741
    ( _pCurve->type == SYMCRYPT_INTERNAL_ECURVE_TYPE_TWISTED_EDWARDS )
2742
2743
#define SYMCRYPT_CURVE_IS_MONTGOMERY_TYPE( _pCurve ) \
2744
1.63k
    ( _pCurve->type == SYMCRYPT_INTERNAL_ECURVE_TYPE_MONTGOMERY )
2745
2746
//
2747
// Scratch space sizes for ECURVE operations
2748
//
2749
//  Overflow protection is enforced when creating the ECURVE objects on
2750
//  the cbScratchCommon, cbScratchScalar, cbScratchScalarMulti, and cbScratchEckey fields.
2751
//
2752
//  All of them are upper bounded by 2^26 (see SymCrypt<CurveType>FillScratchSpaces functions)
2753
//  and since _nPoints is bounded by SYMCRYPT_ECURVE_MULTI_SCALAR_MUL_MAX_NPOINTS = 2, all
2754
//  the macros are bounded by 2^27.
2755
//
2756
2757
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( _pCurve )                 ( (_pCurve)->cbScratchCommon)
2758
330
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_SCALAR_ECURVE_OPERATIONS( _pCurve, _nPoints )       ( (_pCurve)->cbScratchScalar + \
2759
330
                                                                                                (_nPoints) * (_pCurve)->cbScratchScalarMulti )
2760
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_GETSET_VALUE_ECURVE_OPERATIONS( _pCurve )           ( (_pCurve)->cbScratchGetSetValue)
2761
1.42k
#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_ECKEY_ECURVE_OPERATIONS( _pCurve )                  ( (_pCurve)->cbScratchEckey)
2762
2763
typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_ECPOINT {
2764
                    BOOLEAN normalized;     // A flag specifying whether the point is normalized or not. This flag
2765
                                            // makes sense only for PROJECTIVE, JACOBIAN, EXTENDED_PROJECTIVE, and
2766
                                            // SINGLE_PROJECTIVE coordinates. If set to TRUE (non-zero), it means
2767
                                            // that the Z coordinate of the point is equal to 1.
2768
                    PCSYMCRYPT_ECURVE   pCurve; // Handle to the curve which the point is on. Only used in CHKed builds for ASSERTs
2769
                    SYMCRYPT_MAGIC_FIELD
2770
                    // An array of MODELEMENTs. The total size will depend on the MODELEMENT size and the number of MODELEMENTs.
2771
} SYMCRYPT_ECPOINT, *PSYMCRYPT_ECPOINT;
2772
typedef const SYMCRYPT_ECPOINT * PCSYMCRYPT_ECPOINT;
2773
2774
typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_ECKEY {
2775
                    UINT32              fAlgorithmInfo; // Tracks which algorithms the key can be used in
2776
                                                        // Also tracks which per-key selftests have been performed on this key
2777
                                                        // A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_ECKEY_*, and
2778
                                                        // SYMCRYPT_PCT_* values
2779
                    BOOLEAN             hasPrivateKey;  // Set to true if there is a private key set
2780
                    PCSYMCRYPT_ECURVE   pCurve;         // Handle to the curve which created the key
2781
2782
                    PSYMCRYPT_ECPOINT   poPublicKey;    // Public key (ECPOINT)
2783
                    PSYMCRYPT_INT       piPrivateKey;   // Private key
2784
2785
                    SYMCRYPT_MAGIC_FIELD
2786
2787
                    // PublicKey
2788
                    // PrivateKey
2789
} SYMCRYPT_ECKEY;
2790
typedef       SYMCRYPT_ECKEY * PSYMCRYPT_ECKEY;
2791
typedef const SYMCRYPT_ECKEY * PCSYMCRYPT_ECKEY;
2792
2793
SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_802_11_SAE_CUSTOM_STATE {
2794
    PSYMCRYPT_ECURVE        pCurve;
2795
    PCSYMCRYPT_MAC          macAlgorithm;
2796
    PSYMCRYPT_MODELEMENT    peRand;
2797
    PSYMCRYPT_MODELEMENT    peMask;
2798
    PSYMCRYPT_ECPOINT       poPWE;
2799
    BYTE                    counter;
2800
};
2801
2802
//
2803
// XMSS
2804
//
2805
2806
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_XMSS_PARAMS
2807
{
2808
    PCSYMCRYPT_HASH hash;           // hash function
2809
    UINT32          id;             // algorithm identifier
2810
    UINT32          cbHashOutput;   // hash function output size, must be less than or equal to hash->resultSize
2811
    UINT32          nWinternitzWidth;// Wintertnitz coefficient, width of digits in bits (chain length = 2^nWinternitzWidth)
2812
    UINT32          nTotalTreeHeight;// number of layers times the tree height of one layer (each layer has the same height)
2813
    UINT32          nLayers;        // hyper-tree layers, 1 for single tree
2814
    UINT32          cbPrefix;       // length of the domain separator prefix in PRFs
2815
2816
    //
2817
    // The following are derived from the above
2818
    //
2819
    UINT32          len1;           // number of w-bit digits in the hash output to be signed ( len1 = ceil(8n / w) )
2820
    UINT32          len2;           // number of w-bit digits in the checksum
2821
    UINT32          len;            // len1 + len2
2822
    UINT32          nLayerHeight;   // tree height of a single layer (h / d)
2823
    UINT32          cbIdx;          // size of leaf counter in bytes (for single trees cbIdx = 4)
2824
    UINT32          nLeftShift32;   // left shift count to align the checksum digits to MSB of a 32-bit word
2825
    
2826
    BYTE            Reserved[16];   // Reserved for future use
2827
} SYMCRYPT_XMSS_PARAMS;
2828
2829
typedef SYMCRYPT_XMSS_PARAMS* PSYMCRYPT_XMSS_PARAMS;
2830
typedef const SYMCRYPT_XMSS_PARAMS* PCSYMCRYPT_XMSS_PARAMS;
2831
2832
struct _SYMCRYPT_XMSS_KEY;
2833
typedef struct _SYMCRYPT_XMSS_KEY SYMCRYPT_XMSS_KEY;
2834
typedef       SYMCRYPT_XMSS_KEY* PSYMCRYPT_XMSS_KEY;
2835
typedef const SYMCRYPT_XMSS_KEY* PCSYMCRYPT_XMSS_KEY;
2836
2837
2838
2839
#ifndef _PREFAST_
2840
#if SYMCRYPT_CPU_X86
2841
#pragma warning(pop)
2842
#endif
2843
#endif
2844
2845
2846
2847
//////////////////////////////////////////////////////////
2848
//
2849
// Environment macros
2850
//
2851
2852
#ifdef __cplusplus
2853
#define SYMCRYPT_EXTERN_C extern "C" {
2854
#define SYMCRYPT_EXTERN_C_END }
2855
#else
2856
#define SYMCRYPT_EXTERN_C
2857
#define SYMCRYPT_EXTERN_C_END
2858
#endif
2859
2860
//
2861
// Callers of SymCrypt should NOT depend on the function names in these macros.
2862
// The definition of these macros can change in future releases of the library.
2863
//
2864
2865
#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64
2866
typedef struct _SYMCRYPT_EXTENDED_SAVE_DATA      SYMCRYPT_EXTENDED_SAVE_DATA, *PSYMCRYPT_EXTENDED_SAVE_DATA;
2867
2868
#define SYMCRYPT_ENVIRONMENT_DEFS_SAVEYMM( envName ) \
2869
    SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSaveYmmEnv##envName( _Out_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ); \
2870
    SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSaveYmm( _Out_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ) \
2871
        { return SymCryptSaveYmmEnv##envName( pSaveArea ); } \
2872
    \
2873
    VOID SYMCRYPT_CALL SymCryptRestoreYmmEnv##envName( _Inout_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ); \
2874
    VOID SYMCRYPT_CALL SymCryptRestoreYmm( _Inout_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ) \
2875
        { SymCryptRestoreYmmEnv##envName( pSaveArea ); } \
2876
2877
#define SYMCRYPT_ENVIRONMENT_DEFS_SAVEXMM( envName ) \
2878
    SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSaveXmmEnv##envName( _Out_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ); \
2879
    SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSaveXmm( _Out_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ) \
2880
        { return SymCryptSaveXmmEnv##envName( pSaveArea ); } \
2881
    \
2882
    VOID SYMCRYPT_CALL SymCryptRestoreXmmEnv##envName( _Inout_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ); \
2883
    VOID SYMCRYPT_CALL SymCryptRestoreXmm( _Inout_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ) \
2884
        { SymCryptRestoreXmmEnv##envName( pSaveArea ); } \
2885
2886
2887
#else
2888
2889
#define SYMCRYPT_ENVIRONMENT_DEFS_SAVEYMM( envName )
2890
#define SYMCRYPT_ENVIRONMENT_DEFS_SAVEXMM( envName )
2891
2892
#endif
2893
2894
// Environment forwarding functions.
2895
// CPUIDEX is only forwarded on CPUs that have it.
2896
#if SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_X86
2897
#define SYMCRYPT_ENVIRONMENT_FORWARD_CPUIDEX( envName ) \
2898
    VOID SYMCRYPT_CALL SymCryptCpuidExFuncEnv##envName( int cpuInfo[4], int function_id, int subfunction_id ); \
2899
    VOID SYMCRYPT_CALL SymCryptCpuidExFunc( int cpuInfo[4], int function_id, int subfunction_id ) \
2900
        { SymCryptCpuidExFuncEnv##envName( cpuInfo, function_id, subfunction_id ); }
2901
#else
2902
#define SYMCRYPT_ENVIRONMENT_FORWARD_CPUIDEX( envName )
2903
#endif
2904
2905
#define SYMCRYPT_ENVIRONMENT_DEFS( envName ) \
2906
SYMCRYPT_EXTERN_C \
2907
    VOID SYMCRYPT_CALL SymCryptInitEnv##envName( UINT32 version ); \
2908
    VOID SYMCRYPT_CALL SymCryptInit(void) \
2909
        { SymCryptInitEnv##envName( SYMCRYPT_API_VERSION ); } \
2910
    \
2911
    _Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatalEnv##envName( UINT32 fatalCode ); \
2912
    _Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatal( UINT32 fatalCode ) \
2913
        { SymCryptFatalEnv##envName( fatalCode ); } \
2914
    SYMCRYPT_CPU_FEATURES SYMCRYPT_CALL SymCryptCpuFeaturesNeverPresentEnv##envName(void); \
2915
    SYMCRYPT_CPU_FEATURES SYMCRYPT_CALL SymCryptCpuFeaturesNeverPresent(void) \
2916
        { return SymCryptCpuFeaturesNeverPresentEnv##envName(); } \
2917
    \
2918
    SYMCRYPT_ENVIRONMENT_DEFS_SAVEXMM( envName ) \
2919
    SYMCRYPT_ENVIRONMENT_DEFS_SAVEYMM( envName ) \
2920
    \
2921
    VOID SYMCRYPT_CALL SymCryptTestInjectErrorEnv##envName( PBYTE pbBuf, SIZE_T cbBuf ); \
2922
    VOID SYMCRYPT_CALL SymCryptInjectError( PBYTE pbBuf, SIZE_T cbBuf ) \
2923
        { SymCryptTestInjectErrorEnv##envName( pbBuf, cbBuf ); } \
2924
    SYMCRYPT_ENVIRONMENT_FORWARD_CPUIDEX( envName ) \
2925
SYMCRYPT_EXTERN_C_END
2926
2927
//
2928
// To avoid hard-do-diagnose mistakes, we skip defining environment macros in those cases where we
2929
// know they cannot or should not be used.
2930
//
2931
2932
#define SYMCRYPT_ENVIRONMENT_GENERIC                            SYMCRYPT_ENVIRONMENT_DEFS( Generic )
2933
2934
#if defined(EFI) | defined(PCAT) | defined(DIRECT)
2935
#define SYMCRYPT_ENVIRONMENT_WINDOWS_BOOTLIBRARY                SYMCRYPT_ENVIRONMENT_DEFS( WindowsBootlibrary )
2936
#endif
2937
2938
//
2939
// There are no defined symbols that we can use to detect that we are in debugger code
2940
// But this is unlikely to be misused.
2941
//
2942
#define SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELDEBUGGER             SYMCRYPT_ENVIRONMENT_DEFS( WindowsKernelDebugger )
2943
2944
2945
2946
#define SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_LEGACY          SYMCRYPT_ENVIRONMENT_GENERIC
2947
2948
#ifdef NTDDI_VERSION
2949
#if (NTDDI_VERSION >= NTDDI_WIN7)
2950
#define SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_WIN7_N_LATER    SYMCRYPT_ENVIRONMENT_DEFS( WindowsKernelmodeWin7nLater )
2951
#endif
2952
2953
#if (NTDDI_VERSION >= NTDDI_WINBLUE)
2954
#define SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_WIN8_1_N_LATER  SYMCRYPT_ENVIRONMENT_DEFS( WindowsKernelmodeWin8_1nLater )
2955
#endif
2956
2957
#define SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_LATEST          SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_WIN8_1_N_LATER
2958
2959
2960
2961
#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_LEGACY            SYMCRYPT_ENVIRONMENT_GENERIC
2962
2963
#if (NTDDI_VERSION >= NTDDI_WIN7)
2964
#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN7_N_LATER      SYMCRYPT_ENVIRONMENT_DEFS( WindowsUsermodeWin7nLater )
2965
#endif
2966
2967
#if (NTDDI_VERSION >= NTDDI_WINBLUE)
2968
#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN8_1_N_LATER    SYMCRYPT_ENVIRONMENT_DEFS( WindowsUsermodeWin8_1nLater )
2969
#endif
2970
2971
#if (NTDDI_VERSION >= NTDDI_WIN10)
2972
#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN10_SGX         SYMCRYPT_ENVIRONMENT_DEFS( Win10Sgx )
2973
#endif
2974
#endif // NTDDI_VERSION
2975
2976
#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_LATEST            SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN8_1_N_LATER
2977
2978
2979
#define SYMCRYPT_ENVIRONMENT_POSIX_USERMODE                     SYMCRYPT_ENVIRONMENT_DEFS( PosixUsermode )
2980
2981
// For backwards compatibility with previous macro name
2982
#define SYMCRYPT_ENVIRONMENT_LINUX_USERMODE                     SYMCRYPT_ENVIRONMENT_POSIX_USERMODE
2983
2984
2985
#define SYMCRYPT_ENVIRONMENT_OPTEE_TA                           SYMCRYPT_ENVIRONMENT_DEFS( OpteeTa )
2986
2987
//////////////////////////////////////////////////////////
2988
//
2989
// SymCryptWipe & SymCryptWipeKnownSize
2990
//
2991
2992
VOID
2993
SYMCRYPT_CALL
2994
SymCryptWipe(
2995
    _Out_writes_bytes_(cbData)    PVOID   pbData,
2996
    SIZE_T  cbData);
2997
2998
#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM | SYMCRYPT_CPU_ARM64
2999
3000
//
3001
// If the known size is large we call the generic wipe function anyway.
3002
// For small known sizes we perform the wipe inline.
3003
// This is a tradeoff between speed and code size and there are diminishing returns to supporting
3004
// increasingly large sizes.
3005
// We currently put the limit at ~8 native writes, which varies by platform.
3006
//
3007
#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_ARM
3008
#define SYMCRYPT_WIPE_FUNCTION_LIMIT (32)   // If this is increased beyond 127 the code below must be updated.
3009
#elif SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM64
3010
2.73M
#define SYMCRYPT_WIPE_FUNCTION_LIMIT (64)   // If this is increased beyond 127 the code below must be updated.
3011
#else
3012
#error ??
3013
#endif
3014
3015
//
3016
// The buffer analysis code doesn't understand our optimized in-line wiping code
3017
// well enough to conclude it is safe.
3018
//
3019
#pragma prefast(push)
3020
#pragma prefast( disable: 26001 )
3021
3022
FORCEINLINE
3023
VOID
3024
SYMCRYPT_CALL
3025
#pragma prefast( suppress: 6101, "Logic why this properly initializes the pbData buffer is too complicated for prefast" )
3026
SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
3027
2.73M
{
3028
2.73M
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
2.73M
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
141k
    {
3032
141k
        SymCryptWipe(pbData, cbData);
3033
141k
    }
3034
2.59M
    else
3035
2.59M
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
2.59M
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
2.59M
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
2.59M
        if (cbData & 4)
3050
50.5k
        {
3051
50.5k
            cbData -= 4;
3052
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
50.5k
        }
3054
2.59M
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
2.59M
        if (cbData & 16)
3060
51.1k
        {
3061
51.1k
            cbData -= 16;
3062
51.1k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
51.1k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
51.1k
        }
3065
2.59M
        if (cbData & 32)
3066
21.4k
        {
3067
21.4k
            cbData -= 32;
3068
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
21.4k
        }
3073
2.59M
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
2.59M
        if (cbData & 64)
3075
2.47M
        {
3076
2.47M
            cbData -= 64;
3077
2.47M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
2.47M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
2.47M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
2.47M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
2.47M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
2.47M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
2.47M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
2.47M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
2.47M
        }
3086
2.59M
#endif
3087
2.59M
    }
3088
2.73M
}
Unexecuted instantiation: 3des.c:SymCryptWipeKnownSize
Unexecuted instantiation: DesTables.c:SymCryptWipeKnownSize
Unexecuted instantiation: a_dispatch.c:SymCryptWipeKnownSize
Unexecuted instantiation: aes-default-bc.c:SymCryptWipeKnownSize
Unexecuted instantiation: aes-default.c:SymCryptWipeKnownSize
Unexecuted instantiation: aes-key.c:SymCryptWipeKnownSize
Unexecuted instantiation: aes-xmm.c:SymCryptWipeKnownSize
Unexecuted instantiation: aes-ymm.c:SymCryptWipeKnownSize
Unexecuted instantiation: blockciphermodes.c:SymCryptWipeKnownSize
Unexecuted instantiation: ccm.c:SymCryptWipeKnownSize
Unexecuted instantiation: chacha20.c:SymCryptWipeKnownSize
Unexecuted instantiation: desx.c:SymCryptWipeKnownSize
Unexecuted instantiation: ec_dsa.c:SymCryptWipeKnownSize
Unexecuted instantiation: ec_internal_curves.c:SymCryptWipeKnownSize
Unexecuted instantiation: eckey.c:SymCryptWipeKnownSize
Unexecuted instantiation: ecpoint.c:SymCryptWipeKnownSize
Unexecuted instantiation: ecurve.c:SymCryptWipeKnownSize
Unexecuted instantiation: equal.c:SymCryptWipeKnownSize
Unexecuted instantiation: fdef369_mod.c:SymCryptWipeKnownSize
Unexecuted instantiation: fdef_general.c:SymCryptWipeKnownSize
Unexecuted instantiation: fdef_int.c:SymCryptWipeKnownSize
fdef_mod.c:SymCryptWipeKnownSize
Line
Count
Source
3027
2.34M
{
3028
2.34M
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
2.34M
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
0
    {
3032
0
        SymCryptWipe(pbData, cbData);
3033
0
    }
3034
2.34M
    else
3035
2.34M
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
2.34M
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
2.34M
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
2.34M
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
2.34M
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
2.34M
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
2.34M
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
2.34M
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
2.34M
        if (cbData & 64)
3075
2.34M
        {
3076
2.34M
            cbData -= 64;
3077
2.34M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
2.34M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
2.34M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
2.34M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
2.34M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
2.34M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
2.34M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
2.34M
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
2.34M
        }
3086
2.34M
#endif
3087
2.34M
    }
3088
2.34M
}
Unexecuted instantiation: fips_selftest.c:SymCryptWipeKnownSize
Unexecuted instantiation: gcm.c:SymCryptWipeKnownSize
Unexecuted instantiation: ghash.c:SymCryptWipeKnownSize
hkdf.c:SymCryptWipeKnownSize
Line
Count
Source
3027
796
{
3028
796
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
796
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
398
    {
3032
398
        SymCryptWipe(pbData, cbData);
3033
398
    }
3034
398
    else
3035
398
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
398
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
398
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
398
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
398
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
398
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
398
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
398
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
398
        if (cbData & 64)
3075
398
        {
3076
398
            cbData -= 64;
3077
398
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
398
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
398
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
398
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
398
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
398
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
398
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
398
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
398
        }
3086
398
#endif
3087
398
    }
3088
796
}
hmacmd5.c:SymCryptWipeKnownSize
Line
Count
Source
3027
430
{
3028
430
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
430
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
215
    {
3032
215
        SymCryptWipe(pbData, cbData);
3033
215
    }
3034
215
    else
3035
215
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
215
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
215
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
215
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
215
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
215
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
215
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
215
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
215
        if (cbData & 64)
3075
215
        {
3076
215
            cbData -= 64;
3077
215
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
215
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
215
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
215
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
215
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
215
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
215
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
215
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
215
        }
3086
215
#endif
3087
215
    }
3088
430
}
hmacsha1.c:SymCryptWipeKnownSize
Line
Count
Source
3027
584
{
3028
584
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
584
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
292
    {
3032
292
        SymCryptWipe(pbData, cbData);
3033
292
    }
3034
292
    else
3035
292
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
292
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
292
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
292
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
292
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
292
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
292
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
292
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
292
        if (cbData & 64)
3075
292
        {
3076
292
            cbData -= 64;
3077
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
292
        }
3086
292
#endif
3087
292
    }
3088
584
}
hmacsha256.c:SymCryptWipeKnownSize
Line
Count
Source
3027
440
{
3028
440
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
440
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
220
    {
3032
220
        SymCryptWipe(pbData, cbData);
3033
220
    }
3034
220
    else
3035
220
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
220
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
220
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
220
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
220
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
220
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
220
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
220
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
220
        if (cbData & 64)
3075
220
        {
3076
220
            cbData -= 64;
3077
220
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
220
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
220
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
220
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
220
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
220
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
220
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
220
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
220
        }
3086
220
#endif
3087
220
    }
3088
440
}
hmacsha384.c:SymCryptWipeKnownSize
Line
Count
Source
3027
446
{
3028
446
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
446
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
446
    {
3032
446
        SymCryptWipe(pbData, cbData);
3033
446
    }
3034
0
    else
3035
0
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
0
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
0
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
0
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
0
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
0
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
0
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
0
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
0
        if (cbData & 64)
3075
0
        {
3076
0
            cbData -= 64;
3077
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
0
        }
3086
0
#endif
3087
0
    }
3088
446
}
hmacsha512.c:SymCryptWipeKnownSize
Line
Count
Source
3027
586
{
3028
586
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
586
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
586
    {
3032
586
        SymCryptWipe(pbData, cbData);
3033
586
    }
3034
0
    else
3035
0
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
0
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
0
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
0
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
0
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
0
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
0
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
0
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
0
        if (cbData & 64)
3075
0
        {
3076
0
            cbData -= 64;
3077
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
0
        }
3086
0
#endif
3087
0
    }
3088
586
}
Unexecuted instantiation: libmain.c:SymCryptWipeKnownSize
md2.c:SymCryptWipeKnownSize
Line
Count
Source
3027
216
{
3028
216
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
216
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
216
    {
3032
216
        SymCryptWipe(pbData, cbData);
3033
216
    }
3034
0
    else
3035
0
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
0
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
0
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
0
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
0
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
0
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
0
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
0
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
0
        if (cbData & 64)
3075
0
        {
3076
0
            cbData -= 64;
3077
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
0
        }
3086
0
#endif
3087
0
    }
3088
216
}
md4.c:SymCryptWipeKnownSize
Line
Count
Source
3027
1.21k
{
3028
1.21k
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
1.21k
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
92
    {
3032
92
        SymCryptWipe(pbData, cbData);
3033
92
    }
3034
1.11k
    else
3035
1.11k
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
1.11k
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
1.11k
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
1.11k
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
1.11k
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
1.11k
        if (cbData & 16)
3060
559
        {
3061
559
            cbData -= 16;
3062
559
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
559
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
559
        }
3065
1.11k
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
1.11k
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
1.11k
        if (cbData & 64)
3075
559
        {
3076
559
            cbData -= 64;
3077
559
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
559
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
559
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
559
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
559
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
559
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
559
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
559
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
559
        }
3086
1.11k
#endif
3087
1.11k
    }
3088
1.21k
}
md5.c:SymCryptWipeKnownSize
Line
Count
Source
3027
174k
{
3028
174k
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
174k
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
22.9k
    {
3032
22.9k
        SymCryptWipe(pbData, cbData);
3033
22.9k
    }
3034
151k
    else
3035
151k
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
151k
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
151k
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
151k
        if (cbData & 4)
3050
50.5k
        {
3051
50.5k
            cbData -= 4;
3052
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
50.5k
        }
3054
151k
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
151k
        if (cbData & 16)
3060
50.5k
        {
3061
50.5k
            cbData -= 16;
3062
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
50.5k
        }
3065
151k
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
151k
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
151k
        if (cbData & 64)
3075
50.5k
        {
3076
50.5k
            cbData -= 64;
3077
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
50.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
50.5k
        }
3086
151k
#endif
3087
151k
    }
3088
174k
}
Unexecuted instantiation: mlkem.c:SymCryptWipeKnownSize
Unexecuted instantiation: mlkem_primitives.c:SymCryptWipeKnownSize
Unexecuted instantiation: modexp.c:SymCryptWipeKnownSize
pbkdf2.c:SymCryptWipeKnownSize
Line
Count
Source
3027
925
{
3028
925
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
925
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
337
    {
3032
337
        SymCryptWipe(pbData, cbData);
3033
337
    }
3034
588
    else
3035
588
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
588
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
588
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
588
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
588
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
588
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
588
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
588
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
588
        if (cbData & 64)
3075
588
        {
3076
588
            cbData -= 64;
3077
588
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
588
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
588
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
588
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
588
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
588
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
588
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
588
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
588
        }
3086
588
#endif
3087
588
    }
3088
925
}
Unexecuted instantiation: rc4.c:SymCryptWipeKnownSize
Unexecuted instantiation: recoding.c:SymCryptWipeKnownSize
Unexecuted instantiation: rsa_enc.c:SymCryptWipeKnownSize
Unexecuted instantiation: rsa_padding.c:SymCryptWipeKnownSize
Unexecuted instantiation: rsakey.c:SymCryptWipeKnownSize
Unexecuted instantiation: scsTools.c:SymCryptWipeKnownSize
Unexecuted instantiation: selftest.c:SymCryptWipeKnownSize
sha1.c:SymCryptWipeKnownSize
Line
Count
Source
3027
60.9k
{
3028
60.9k
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
60.9k
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
22.4k
    {
3032
22.4k
        SymCryptWipe(pbData, cbData);
3033
22.4k
    }
3034
38.5k
    else
3035
38.5k
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
38.5k
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
38.5k
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
38.5k
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
38.5k
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
38.5k
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
38.5k
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
38.5k
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
38.5k
        if (cbData & 64)
3075
38.5k
        {
3076
38.5k
            cbData -= 64;
3077
38.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
38.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
38.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
38.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
38.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
38.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
38.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
38.5k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
38.5k
        }
3086
38.5k
#endif
3087
38.5k
    }
3088
60.9k
}
sha256.c:SymCryptWipeKnownSize
Line
Count
Source
3027
54.3k
{
3028
54.3k
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
54.3k
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
11.5k
    {
3032
11.5k
        SymCryptWipe(pbData, cbData);
3033
11.5k
    }
3034
42.8k
    else
3035
42.8k
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
42.8k
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
42.8k
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
42.8k
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
42.8k
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
42.8k
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
42.8k
        if (cbData & 32)
3066
21.4k
        {
3067
21.4k
            cbData -= 32;
3068
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
21.4k
        }
3073
42.8k
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
42.8k
        if (cbData & 64)
3075
21.4k
        {
3076
21.4k
            cbData -= 64;
3077
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
21.4k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
21.4k
        }
3086
42.8k
#endif
3087
42.8k
    }
3088
54.3k
}
Unexecuted instantiation: sha3_256.c:SymCryptWipeKnownSize
Unexecuted instantiation: sha3_384.c:SymCryptWipeKnownSize
Unexecuted instantiation: sha3_512.c:SymCryptWipeKnownSize
sha512.c:SymCryptWipeKnownSize
Line
Count
Source
3027
93.1k
{
3028
93.1k
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
93.1k
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
80.9k
    {
3032
80.9k
        SymCryptWipe(pbData, cbData);
3033
80.9k
    }
3034
12.2k
    else
3035
12.2k
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
12.2k
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
12.2k
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
12.2k
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
12.2k
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
12.2k
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
12.2k
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
12.2k
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
12.2k
        if (cbData & 64)
3075
12.2k
        {
3076
12.2k
            cbData -= 64;
3077
12.2k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
12.2k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
12.2k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
12.2k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
12.2k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
12.2k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
12.2k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
12.2k
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
12.2k
        }
3086
12.2k
#endif
3087
12.2k
    }
3088
93.1k
}
Unexecuted instantiation: shake.c:SymCryptWipeKnownSize
sp800_108.c:SymCryptWipeKnownSize
Line
Count
Source
3027
68
{
3028
68
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
68
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
34
    {
3032
34
        SymCryptWipe(pbData, cbData);
3033
34
    }
3034
34
    else
3035
34
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
34
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
34
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
34
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
34
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
34
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
34
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
34
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
34
        if (cbData & 64)
3075
34
        {
3076
34
            cbData -= 64;
3077
34
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
34
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
34
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
34
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
34
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
34
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
34
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
34
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
34
        }
3086
34
#endif
3087
34
    }
3088
68
}
tlsprf.c:SymCryptWipeKnownSize
Line
Count
Source
3027
454
{
3028
454
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
454
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
108
    {
3032
108
        SymCryptWipe(pbData, cbData);
3033
108
    }
3034
346
    else
3035
346
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
346
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
346
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
346
        if (cbData & 4)
3050
27
        {
3051
27
            cbData -= 4;
3052
27
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
27
        }
3054
346
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
346
        if (cbData & 16)
3060
54
        {
3061
54
            cbData -= 16;
3062
54
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
54
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
54
        }
3065
346
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
346
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
346
        if (cbData & 64)
3075
292
        {
3076
292
            cbData -= 64;
3077
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
292
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
292
        }
3086
346
#endif
3087
346
    }
3088
454
}
Unexecuted instantiation: xmss.c:SymCryptWipeKnownSize
Unexecuted instantiation: xtsaes.c:SymCryptWipeKnownSize
Unexecuted instantiation: AesTables.c:SymCryptWipeKnownSize
Unexecuted instantiation: ScsTable.c:SymCryptWipeKnownSize
Unexecuted instantiation: aes-asm.c:SymCryptWipeKnownSize
Unexecuted instantiation: aes-c.c:SymCryptWipeKnownSize
Unexecuted instantiation: crt.c:SymCryptWipeKnownSize
Unexecuted instantiation: dh.c:SymCryptWipeKnownSize
Unexecuted instantiation: dl_internal_groups.c:SymCryptWipeKnownSize
Unexecuted instantiation: dlgroup.c:SymCryptWipeKnownSize
Unexecuted instantiation: dlkey.c:SymCryptWipeKnownSize
Unexecuted instantiation: dsa.c:SymCryptWipeKnownSize
Unexecuted instantiation: ec_dh.c:SymCryptWipeKnownSize
Unexecuted instantiation: ec_dispatch.c:SymCryptWipeKnownSize
Unexecuted instantiation: ec_montgomery.c:SymCryptWipeKnownSize
Unexecuted instantiation: ec_mul.c:SymCryptWipeKnownSize
Unexecuted instantiation: ec_short_weierstrass.c:SymCryptWipeKnownSize
Unexecuted instantiation: ec_twisted_edwards.c:SymCryptWipeKnownSize
Unexecuted instantiation: gen_int.c:SymCryptWipeKnownSize
Unexecuted instantiation: hash.c:SymCryptWipeKnownSize
Unexecuted instantiation: marvin32.c:SymCryptWipeKnownSize
Unexecuted instantiation: primes.c:SymCryptWipeKnownSize
Unexecuted instantiation: sha256-xmm.c:SymCryptWipeKnownSize
sha3.c:SymCryptWipeKnownSize
Line
Count
Source
3027
526
{
3028
526
    volatile BYTE * pb = (volatile BYTE *)pbData;
3029
3030
526
    if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)
3031
526
    {
3032
526
        SymCryptWipe(pbData, cbData);
3033
526
    }
3034
0
    else
3035
0
    {
3036
        //
3037
        // We assume that pb is aligned, so we wipe from the end to the front to keep alignment.
3038
        //
3039
0
        if (cbData & 1)
3040
0
        {
3041
0
            cbData--;
3042
0
            SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);
3043
0
        }
3044
0
        if (cbData & 2)
3045
0
        {
3046
0
            cbData -= 2;
3047
0
            SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);
3048
0
        }
3049
0
        if (cbData & 4)
3050
0
        {
3051
0
            cbData -= 4;
3052
0
            SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);
3053
0
        }
3054
0
        if (cbData & 8)
3055
0
        {
3056
0
            cbData -= 8;
3057
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3058
0
        }
3059
0
        if (cbData & 16)
3060
0
        {
3061
0
            cbData -= 16;
3062
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3063
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3064
0
        }
3065
0
        if (cbData & 32)
3066
0
        {
3067
0
            cbData -= 32;
3068
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3069
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3070
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3071
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3072
0
        }
3073
0
#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 64
3074
0
        if (cbData & 64)
3075
0
        {
3076
0
            cbData -= 64;
3077
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);
3078
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);
3079
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);
3080
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);
3081
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);
3082
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);
3083
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);
3084
0
            SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);
3085
0
        }
3086
0
#endif
3087
0
    }
3088
526
}
3089
3090
#pragma prefast(pop)
3091
3092
#else // Platform switch for SymCryptWipeKnownSize
3093
3094
FORCEINLINE
3095
VOID
3096
SYMCRYPT_CALL
3097
SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)
3098
0
{
3099
0
    SymCryptWipe(pbData, cbData);
3100
0
}
3101
3102
#endif  // Platform switch for SymCryptWipeKnownSize
3103
3104
// Set this flag to 1 to enable FIPS checks in the SymCrypt module.
3105
#ifndef SYMCRYPT_DO_FIPS_SELFTESTS
3106
#define SYMCRYPT_DO_FIPS_SELFTESTS 0
3107
#endif
3108
3109
40
#define SYMCRYPT_FIPS_ASSERT(x) { if(!(x)){ SymCryptFatal('FIPS'); } }
3110
3111
// Flags for FIPS on-demand selftests. When an on-demand selftest succeeds, the corresponding flag
3112
// will be set in g_SymCryptFipsSelftestsPerformed. Other selftests are performed automatically
3113
// when the module is loaded, so they don't have a corresponding flag.
3114
typedef enum _SYMCRYPT_SELFTEST_ALGORITHM {
3115
    SYMCRYPT_SELFTEST_ALGORITHM_NONE    =  0x0,
3116
    SYMCRYPT_SELFTEST_ALGORITHM_STARTUP =  0x1,
3117
    SYMCRYPT_SELFTEST_ALGORITHM_DSA     =  0x2,
3118
    SYMCRYPT_SELFTEST_ALGORITHM_ECDSA   =  0x4,
3119
    SYMCRYPT_SELFTEST_ALGORITHM_RSA     =  0x8,
3120
    SYMCRYPT_SELFTEST_ALGORITHM_DH      = 0x10,
3121
    SYMCRYPT_SELFTEST_ALGORITHM_ECDH    = 0x20,
3122
    SYMCRYPT_SELFTEST_ALGORITHM_MLKEM   = 0x40,
3123
} SYMCRYPT_SELFTEST_ALGORITHM;
3124
3125
// Takes values which are some bitwise OR combination of SYMCRYPT_SELFTEST_ALGORITHM values
3126
// Specified as UINT32 as we will update with 32 bit atomics, and compilers may choose to make enum
3127
// types smaller than 32 bits.
3128
extern UINT32 g_SymCryptFipsSelftestsPerformed;
3129
3130
UINT32
3131
SYMCRYPT_CALL
3132
SymCryptFipsGetSelftestsPerformed(void);
3133
// Returns current value of g_SymCryptFipsSelftestsPerformed so callers may inspect which FIPS
3134
// algorithm selftests have run
3135
3136
// Flags for per-key selftests.
3137
// When an asymmetric key is generated or imported, and SYMCRYPT_FLAG_KEY_NO_FIPS is not specified,
3138
// some selftests must be performed on the key, before its operational use in an algorithm, to
3139
// comply with FIPS.
3140
// The algorithms the key may be used in will be tracked in the key's fAlgorithmInfo field, as a
3141
// bitwise OR of SYMCRYPT_FLAG_<keytype>_<algorithm> (e.g. SYMCRYPT_FLAG_DLKEY_DH).
3142
// This field will also track which per-key selftests have been run on the key using the below flags
3143
// We want to track which selftests have been run independently of which algorithms the key may be
3144
// used in as in some scenarios at key generation / import time we may not know what algorithm the
3145
// key will actually be used in. Tracking the run per-key selftests in fAlgorithmInfo allows us to
3146
// defer running expensive tests until we know they are required (e.g. if we generate an Eckey which
3147
// may be used in ECDH or ECDSA, and only use it for ECDH, the ECDSA PCT is deferred until we first
3148
// attempt to use the key in ECDSA, or export the private key).
3149
//
3150
// For clarity, SYMCRYPT_PCT_* should be used instead of SYMCRYPT_SELFTEST_KEY_* going forward.
3151
// The latter is retained for compatibility with existing code, but may be removed in a future
3152
// breaking change.
3153
3154
// Dlkey selftest flags
3155
// DSA Pairwise Consistency Test to be run generated keys
3156
#define SYMCRYPT_SELFTEST_KEY_DSA       (0x1)
3157
#define SYMCRYPT_PCT_DSA                SYMCRYPT_SELFTEST_KEY_DSA
3158
3159
// Eckey selftest flags
3160
// ECDSA Pairwise Consistency Test to be run generated keys
3161
#define SYMCRYPT_SELFTEST_KEY_ECDSA     (0x1)
3162
#define SYMCRYPT_PCT_ECDSA              SYMCRYPT_SELFTEST_KEY_ECDSA
3163
3164
// Rsakey selftest flags
3165
// RSA Pairwise Consistency Test to be run generated keys
3166
#define SYMCRYPT_SELFTEST_KEY_RSA_SIGN  (0x1)
3167
#define SYMCRYPT_PCT_RSA_SIGN           SYMCRYPT_SELFTEST_KEY_RSA_SIGN
3168
3169
UINT32
3170
SYMCRYPT_CALL
3171
SymCryptDeprecatedStatusIndicator(PBYTE pbOutput, UINT32 cbOutput);
3172
//
3173
// Returns the FIPS Approved Services Status Indicator as an ASCII string.
3174
// This API is required to satisfy FIPS 140-3 requirements, but is *not* recommended
3175
// to be used in production code. It should be considered unstable,
3176
// and may be removed at any time.
3177
// 
3178
// The output string will be copied to pbOutput if the size of the buffer 
3179
// cbOutput is large enough. The function returns the required buffer size
3180
// when pbOutput is passed as NULL. If pbOutput is not NULL, the function 
3181
// returns the number of bytes copied to pbOutput.
3182
//