Path: blob/master/libs/symcrypt/inc/symcrypt_internal.h
15010 views
//1// SymCrypt_internal.h2//3// Copyright (c) Microsoft Corporation. Licensed under the MIT license.4//56//7// This file contains information that is internal to the symcrypt library,8// but which still needs to be known to the compiler to be able to use the library.9// This includes structure declarations and all support for inline implementations10// of some of the library functions.11// Information in this file is not part of the API and can change at any time.12//1314#pragma GCC diagnostic ignored "-Wunknown-pragmas"1516//17// We use Prefast pragmas, but they are not recognized by the compiler.18// We disable the 'unknown pragma' warning if we are not in prefast mode.19//20#ifndef _PREFAST_21#pragma warning(disable:4068)22#endif2324//==============================================================================================25// PLATFORM/COMPILER DETECTION26//==============================================================================================2728#define SYMCRYPT_PLATFORM_WINDOWS 029#define SYMCRYPT_PLATFORM_APPLE 0 // macOS and other Apple platforms30#define SYMCRYPT_PLATFORM_UNIX 0 // Linux and other Unix-likes, besides macOS. Must support POSIX.3132#if defined(_WIN32)33#undef SYMCRYPT_PLATFORM_WINDOWS34#define SYMCRYPT_PLATFORM_WINDOWS 135#elif defined(__APPLE__)36#undef SYMCRYPT_PLATFORM_APPLE37#define SYMCRYPT_PLATFORM_APPLE 138#elif (defined(linux) || defined(__unix__))39#undef SYMCRYPT_PLATFORM_UNIX40#define SYMCRYPT_PLATFORM_UNIX 141#endif4243#define SYMCRYPT_MS_VC 0 // Microsoft compiler (cl.exe - Visual Studio/MSBuild)44#define SYMCRYPT_GNUC 0 // GCC and compatible compilers (including Clang)4546#if defined(_MSC_VER)47#undef SYMCRYPT_MS_VC48#define SYMCRYPT_MS_VC 149#elif defined(__GNUC__)50#undef SYMCRYPT_GNUC51#define SYMCRYPT_GNUC 152#else53#error Unsupported compiler54#endif5556#if SYMCRYPT_MS_VC5758// This should go somewhere else. Same in the other #if branches.59#define SYMCRYPT_ANYSIZE_ARRAY 160#define SYMCRYPT_NOINLINE __declspec(noinline)61#define SYMCRYPT_CDECL __cdecl62#define SYMCRYPT_FASTCALL __fastcall6364#define SYMCRYPT_UNALIGNED6566#elif SYMCRYPT_GNUC6768// Ignore the multi-character character constant warnings69#pragma GCC diagnostic ignored "-Wmultichar"70#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"7172#define SYMCRYPT_ANYSIZE_ARRAY 173#define SYMCRYPT_NOINLINE __attribute__ ((noinline))74#define SYMCRYPT_UNALIGNED75#define SYMCRYPT_CDECL76#define SYMCRYPT_FASTCALL __attribute__((fastcall))7778#endif7980#ifdef __clang__81#pragma clang diagnostic ignored "-Wmultichar"82#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"83#pragma clang diagnostic ignored "-Wincompatible-pointer-types-discards-qualifiers"84#endif8586//==============================================================================================87// PLATFORM SPECIFICS88//==============================================================================================8990//91// SYMCRYPT_CALL & SYMCRYPT_ALIGN92//93// SYMCRYPT_CALL is a macro that selects the calling convention used by the library.94// Crypto functions often have to perform very many small operations, and a fast calling convention is95// preferable. We use __fastcall on platforms that support it.96//97// SYMCRYPT_ALIGN is the default alignment for the platform.98// On platforms that have alignment restrictions the default alignment should be large enough that99// an aligned BYTE * can be cast to a pointer to a UINT32 and be used.100//101//102// The SYMCRYPT_IGNORE_PLATFORM macro can be defined to switch off any platform-specific103// optimizations and run just the C implementations.104// The rest of the library uses SYMCRYPT_CPU_* macros to make platform decisions.105//106//107// WARNING: both the library and the calling application must be compiled with the same108// set of flags, as the flags affect things like the structure layout and size and109// the calling convention, both of which need to be in sync between the lib and the caller.110//111112//#define SYMCRYPT_IGNORE_PLATFORM // #defining this flag disables all platform optimizations.113114#define SYMCRYPT_CPU_X86 0115#define SYMCRYPT_CPU_AMD64 0116#define SYMCRYPT_CPU_ARM 0117#define SYMCRYPT_CPU_ARM64 0118#define SYMCRYPT_CPU_UNKNOWN 0119120#if (defined( _X86_ ) || defined( _M_IX86 ) || defined( __i386__ )) && !defined ( SYMCRYPT_IGNORE_PLATFORM )121122#undef SYMCRYPT_CPU_X86123#define SYMCRYPT_CPU_X86 1124125#define SYMCRYPT_CALL SYMCRYPT_FASTCALL126#define SYMCRYPT_ALIGN_VALUE 4127128#ifndef _PREFAST_129#pragma warning(push)130#pragma warning(disable:4359) // *** Alignment specifier is less than actual alignment131#endif132133#elif (defined( _ARM64_ ) || defined( _ARM64EC_ ) || defined( _M_ARM64 ) || defined( __aarch64__ ) || defined(__arm64ec__)) && !defined( SYMCRYPT_IGNORE_PLATFORM )134135#undef SYMCRYPT_CPU_ARM64136#define SYMCRYPT_CPU_ARM64 1137#define SYMCRYPT_CALL138#define SYMCRYPT_ALIGN_VALUE 16139140#elif (defined( _AMD64_ ) || defined( _M_AMD64 ) || defined( __amd64__ )) && !defined ( SYMCRYPT_IGNORE_PLATFORM )141142#undef SYMCRYPT_CPU_AMD64143#define SYMCRYPT_CPU_AMD64 1144145#define SYMCRYPT_CALL146#define SYMCRYPT_ALIGN_VALUE 16147148#elif (defined( _ARM_ ) || defined( _M_ARM ) || defined( __arm__ )) && !defined( SYMCRYPT_IGNORE_PLATFORM )149150#undef SYMCRYPT_CPU_ARM151#define SYMCRYPT_CPU_ARM 1152#define SYMCRYPT_CALL153#define SYMCRYPT_ALIGN_VALUE 8154155#elif defined( SYMCRYPT_IGNORE_PLATFORM )156157#undef SYMCRYPT_CPU_UNKNOWN158#define SYMCRYPT_CPU_UNKNOWN 1159#define SYMCRYPT_CALL160#define SYMCRYPT_ALIGN_VALUE 16161162#ifndef _PREFAST_163#pragma warning(push)164#pragma warning(disable:4359) // *** Alignment specifier is less than actual alignment165#endif166167#else168169#error Unknown CPU platform170171#endif // SYMCRYPT_CALL platforms switch172173174//175// Datatypes used by the SymCrypt library. This ensures compatibility176// with multiple environments, such as Windows, iOS, and Android.177//178179#if SYMCRYPT_PLATFORM_WINDOWS180181//182// Types included in intsafe.h:183// BYTE,184// INT16, UINT16,185// INT32, UINT32,186// INT64, UINT64,187// UINT_PTR188// and macro:189// UINT32_MAX190//191#include <intsafe.h>192193#else194195#include <stdint.h>196197typedef uint8_t BYTE;198199#ifndef UINT32_MAX200#define UINT32_MAX (0xffffffff)201#endif202203#ifndef TRUE204#define TRUE 0x01205#endif206207#ifndef FALSE208#define FALSE 0x00209#endif210211// Size_t212typedef size_t SIZE_T;213214#ifndef SIZE_T_MAX215#define SIZE_T_MAX SIZE_MAX216#endif217218typedef int BOOL;219220typedef int8_t INT8, *PINT8;221typedef int16_t INT16, *PINT16;222typedef int32_t INT32, *PINT32;223typedef int64_t INT64, *PINT64;224typedef uint8_t UINT8, *PUINT8;225typedef uint16_t UINT16, *PUINT16;226typedef uint32_t UINT32, *PUINT32;227typedef uint64_t UINT64, *PUINT64;228229// minwindef.h230typedef char CHAR;231232#endif //WIN32233234#include <stddef.h>235236//237// Pointer types238//239typedef BYTE * PBYTE;240typedef const BYTE * PCBYTE;241242typedef UINT16 * PUINT16;243typedef const UINT16 * PCUINT16;244245typedef UINT32 * PUINT32;246typedef const UINT32 * PCUINT32;247248typedef UINT64 * PUINT64;249typedef const UINT64 * PCUINT64;250251// Void252253#ifndef VOID254#define VOID void255#endif256257typedef void * PVOID;258typedef const void * PCVOID;259260// winnt.h261typedef BYTE BOOLEAN;262263// Useful macros for structs264#define SYMCRYPT_FIELD_OFFSET(type, field) (offsetof(type, field))265#define SYMCRYPT_FIELD_SIZE(type, field) (sizeof( ((type *)0)->field ))266267#if SYMCRYPT_MS_VC268269#ifndef FORCEINLINE270#if (_MSC_VER >= 1200)271#define FORCEINLINE __forceinline272#else273#define FORCEINLINE __inline274#endif275#endif276277#else278279#undef FORCEINLINE280#define FORCEINLINE static inline281282#endif283284C_ASSERT( (SYMCRYPT_ALIGN_VALUE & (SYMCRYPT_ALIGN_VALUE - 1 )) == 0 );285#define SYMCRYPT_ALIGN_UP( _p ) ((PBYTE) ( ((SIZE_T) (_p) + SYMCRYPT_ALIGN_VALUE - 1) & ~(SYMCRYPT_ALIGN_VALUE - 1 ) ) )286287#if SYMCRYPT_MS_VC288#define SYMCRYPT_ALIGN_AT(alignment) __declspec(align(alignment))289#define SYMCRYPT_WEAK_SYMBOL290#elif SYMCRYPT_GNUC291#define SYMCRYPT_ALIGN_AT(alignment) __attribute__((aligned(alignment)))292#define SYMCRYPT_WEAK_SYMBOL __attribute__((weak))293#else294#define SYMCRYPT_ALIGN_AT(alignment)295#define SYMCRYPT_WEAK_SYMBOL296#endif297#define SYMCRYPT_ALIGN_TYPE_AT(typename, alignment) typename SYMCRYPT_ALIGN_AT(alignment)298#define SYMCRYPT_ALIGN SYMCRYPT_ALIGN_AT(SYMCRYPT_ALIGN_VALUE)299#define SYMCRYPT_ALIGN_STRUCT SYMCRYPT_ALIGN_TYPE_AT(struct, SYMCRYPT_ALIGN_VALUE)300#define SYMCRYPT_ALIGN_UNION SYMCRYPT_ALIGN_TYPE_AT(union, SYMCRYPT_ALIGN_VALUE)301302303#define SYMCRYPT_MAX( _a, _b ) ((_a)>(_b)?(_a):(_b))304#define SYMCRYPT_MIN( _a, _b ) ((_a)<(_b)?(_a):(_b))305306#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64307//308// XMM related declarations, used in data structures.309//310#pragma prefast(push)311#pragma prefast(disable: 28251, "Windows headers define _mm_clflush with SAL annotation, Intel header doesn't have SAL annotation leading to inconsistent annotation errors")312#include <emmintrin.h>313#pragma prefast(pop)314#endif315316317//318// To provide quick error detection we have magic values in all319// our data structures, but only in CHKed builds.320// Our magic value depends on the address of the structure.321// This has the advantage that we detect blind memcpy's of our data structures.322// Memcpy is not supported as it limits what the library is allowed to do.323// Where needed the library provides for copy functions of its internal data structures.324//325#if SYMCRYPT_DEBUG326#define SYMCRYPT_MAGIC_ENABLED327#endif328329#if defined(SYMCRYPT_MAGIC_ENABLED )330331#define SYMCRYPT_MAGIC_FIELD SIZE_T magic;332#define SYMCRYPT_MAGIC_VALUE( p ) ((SIZE_T) p + 'S1mv' + SYMCRYPT_API_VERSION)333334335#define SYMCRYPT_SET_MAGIC( p ) {(p)->magic = SYMCRYPT_MAGIC_VALUE( p );}336#define SYMCRYPT_CHECK_MAGIC( p ) {if((p)->magic!=SYMCRYPT_MAGIC_VALUE(p)) SymCryptFatal('magc');}337#define SYMCRYPT_WIPE_MAGIC( p ) {(p)->magic = 0;}338339#else340341//342// We define the magic field even for FRE builds, because we get too many343// hard-to-debug problems with people who accidentally mix FRE headers with CHKed libraries,344// or the other way around.345// E.g. BitLocker only publishes the FRE version of their library, and building a CHKed binary with346// that FRE lib crashes347//348349#define SYMCRYPT_MAGIC_FIELD SIZE_T magic;350#define SYMCRYPT_SET_MAGIC( p )351#define SYMCRYPT_CHECK_MAGIC( p )352#define SYMCRYPT_WIPE_MAGIC( p )353354#endif355356//357// CPU feature detection infrastructure358//359360#if !SYMCRYPT_PLATFORM_WINDOWS361// Forward declarations for CPUID intrinsic replacements362void __cpuidex(int CPUInfo[4], int InfoType, int ECXValue);363#endif364365#if SYMCRYPT_CPU_ARM || SYMCRYPT_CPU_ARM64366367#define SYMCRYPT_CPU_FEATURE_NEON 0x01368#define SYMCRYPT_CPU_FEATURE_NEON_AES 0x02369#define SYMCRYPT_CPU_FEATURE_NEON_PMULL 0x04370#define SYMCRYPT_CPU_FEATURE_NEON_SHA256 0x08371372#elif SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64373374//375// We keep the most commonly tested bits in the least significant byte, to make it easier for the compiler to optimize376// There is a many to one relationship between CPUID feature flags and SYMCRYPT_CPU_FEATURE_XXX bits377// since a SYMCRYPT_CPU_FEATURE_XXX could require multiple CPUID features.378379#define SYMCRYPT_CPU_FEATURE_SSE2 0x0001 // includes SSE, SSE2380#define SYMCRYPT_CPU_FEATURE_SSSE3 0x0002 // includes SSE, SSE2, SSE3, SSSE3381#define SYMCRYPT_CPU_FEATURE_AESNI 0x0004382#define SYMCRYPT_CPU_FEATURE_PCLMULQDQ 0x0008383#define SYMCRYPT_CPU_FEATURE_AVX2 0x0010 // includes AVX, AVX2 - also indicates support for saving/restoring Ymm registers384#define SYMCRYPT_CPU_FEATURE_SAVEXMM_NOFAIL 0x0020 // if SymCryptSaveXmm() will never fail385#define SYMCRYPT_CPU_FEATURE_SHANI 0x0040386#define SYMCRYPT_CPU_FEATURE_BMI2 0x0080 // MULX, RORX, SARX, SHLX, SHRX387388#define SYMCRYPT_CPU_FEATURE_ADX 0x0100 // ADCX, ADOX389#define SYMCRYPT_CPU_FEATURE_RDRAND 0x0200390#define SYMCRYPT_CPU_FEATURE_RDSEED 0x0400391#define SYMCRYPT_CPU_FEATURE_VAES 0x0800 // support for VAES and VPCLMULQDQ (may only be supported on Ymm registers (i.e. Zen3))392#define SYMCRYPT_CPU_FEATURE_AVX512 0x1000 // includes F, VL, DQ, BW (VL allows AVX-512 instructions to be used on Xmm and Ymm registers)393// also indicates support for saving/restoring additional AVX-512 state394395#define SYMCRYPT_CPU_FEATURE_CMPXCHG16B 0x2000 // Compare and Swap 128b value396397#endif398399typedef UINT32 SYMCRYPT_CPU_FEATURES;400401//402// We have two feature fields.403// g_SymCryptCpuFeaturesNotPresent reports with features are not present on the current CPU404// SymCryptCpuFeaturesNeverPresent() is a function that returns a static (compiler-predictable) value,405// and allows the environment to lock out features in a way that the compiler can optimize away all the code that uses these features.406// Using a function allows the environment macro to forward it to an environment-specific function.407//408409extern SYMCRYPT_CPU_FEATURES g_SymCryptCpuFeaturesNotPresent;410411SYMCRYPT_CPU_FEATURES412SYMCRYPT_CALL413SymCryptCpuFeaturesNeverPresent(void);414415#define SYMCRYPT_CPU_FEATURES_PRESENT( x ) ( ((x) & SymCryptCpuFeaturesNeverPresent()) == 0 && ( (x) & g_SymCryptCpuFeaturesNotPresent ) == 0 )416417//418// VOLATILE MEMORY ACCESS419//420// These macros are used to explicitly handle volatile memory access independent of compiler settings.421// If volatile memory is accessed directly without using the appropriate macro, MSVC may emit warning422// C4746, because the volatile semantics depend on the value of the /volatile flag, which can result in423// undesired hardware memory barriers that impact performance.424//425// More info:426// https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-c4746?view=msvc-170427// https://docs.microsoft.com/en-us/cpp/build/reference/volatile-volatile-keyword-interpretation?view=msvc-170428//429430#if SYMCRYPT_MS_VC // Microsoft VC++ Compiler431432#if SYMCRYPT_CPU_ARM || SYMCRYPT_CPU_ARM64433#define SYMCRYPT_INTERNAL_VOLATILE_READ8( _p ) ( __iso_volatile_load8( (const volatile char*)(_p) ) )434#define SYMCRYPT_INTERNAL_VOLATILE_READ16( _p ) ( __iso_volatile_load16( (const volatile short*)(_p) ) )435#define SYMCRYPT_INTERNAL_VOLATILE_READ32( _p ) ( __iso_volatile_load32( (const volatile int*)(_p) ) )436#define SYMCRYPT_INTERNAL_VOLATILE_READ64( _p ) ( __iso_volatile_load64( (const volatile __int64*)(_p) ) )437438#define SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v ) ( __iso_volatile_store8( (volatile char*)(_p), (_v) ) )439#define SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v ) ( __iso_volatile_store16( (volatile short*)(_p), (_v) ) )440#define SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v ) ( __iso_volatile_store32( (volatile int*)(_p), (_v) ) )441#define SYMCRYPT_INTERNAL_VOLATILE_WRITE64( _p, _v ) ( __iso_volatile_store64( (volatile __int64*)(_p), (_v) ) )442#elif SYMCRYPT_CPU_X86 || SYMCRYPT_CPU_AMD64443#define SYMCRYPT_INTERNAL_VOLATILE_READ8( _p ) ( *((const volatile BYTE*) (_p)) )444#define SYMCRYPT_INTERNAL_VOLATILE_READ16( _p ) ( *((const volatile UINT16*)(_p)) )445#define SYMCRYPT_INTERNAL_VOLATILE_READ32( _p ) ( *((const volatile UINT32*)(_p)) )446#define SYMCRYPT_INTERNAL_VOLATILE_READ64( _p ) ( *((const volatile UINT64*)(_p)) )447448#define SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v ) ( *((volatile BYTE*) (_p)) = (_v) )449#define SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v ) ( *((volatile UINT16*)(_p)) = (_v) )450#define SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v ) ( *((volatile UINT32*)(_p)) = (_v) )451#define SYMCRYPT_INTERNAL_VOLATILE_WRITE64( _p, _v ) ( *((volatile UINT64*)(_p)) = (_v) )452#else // Temporary workaround for CMake compilation issues on Windows. Assume X86/ADM64.453#define SYMCRYPT_INTERNAL_VOLATILE_READ8( _p ) ( *((const volatile BYTE*) (_p)) )454#define SYMCRYPT_INTERNAL_VOLATILE_READ16( _p ) ( *((const volatile UINT16*)(_p)) )455#define SYMCRYPT_INTERNAL_VOLATILE_READ32( _p ) ( *((const volatile UINT32*)(_p)) )456#define SYMCRYPT_INTERNAL_VOLATILE_READ64( _p ) ( *((const volatile UINT64*)(_p)) )457458#define SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v ) ( *((volatile BYTE*) (_p)) = (_v) )459#define SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v ) ( *((volatile UINT16*)(_p)) = (_v) )460#define SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v ) ( *((volatile UINT32*)(_p)) = (_v) )461#define SYMCRYPT_INTERNAL_VOLATILE_WRITE64( _p, _v ) ( *((volatile UINT64*)(_p)) = (_v) )462#endif463464#elif SYMCRYPT_GNUC465466#if !SYMCRYPT_CPU_ARM467#define SYMCRYPT_INTERNAL_VOLATILE_READ8( _p ) ( *((const volatile BYTE*) (_p)) )468#define SYMCRYPT_INTERNAL_VOLATILE_READ16( _p ) ( *((const volatile UINT16*)(_p)) )469#define SYMCRYPT_INTERNAL_VOLATILE_READ32( _p ) ( *((const volatile UINT32*)(_p)) )470#define SYMCRYPT_INTERNAL_VOLATILE_READ64( _p ) ( *((const volatile UINT64*)(_p)) )471472#define SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v ) ( *((volatile BYTE*) (_p)) = (_v) )473#define SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v ) ( *((volatile UINT16*)(_p)) = (_v) )474#define SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v ) ( *((volatile UINT32*)(_p)) = (_v) )475#define SYMCRYPT_INTERNAL_VOLATILE_WRITE64( _p, _v ) ( *((volatile UINT64*)(_p)) = (_v) )476#else // SYMCRYPT_CPU_ARM477#define SYMCRYPT_INTERNAL_VOLATILE_READ8( _p ) ( *((const volatile BYTE*) (_p)) )478#define SYMCRYPT_INTERNAL_VOLATILE_READ16( _p ) ( *((const volatile UINT16*)(_p)) )479#define SYMCRYPT_INTERNAL_VOLATILE_READ32( _p ) ( *((const volatile UINT32*)(_p)) )480#define SYMCRYPT_INTERNAL_VOLATILE_READ64( p ) ( (UINT64)SYMCRYPT_INTERNAL_VOLATILE_READ32(&((PBYTE)p)[4]) << 32 | SYMCRYPT_INTERNAL_VOLATILE_READ32(&((PBYTE)p)[0]) )481482#define SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v ) ( *((volatile BYTE*) (_p)) = (_v) )483#define SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v ) ( *((volatile UINT16*)(_p)) = (_v) )484#define SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v ) ( *((volatile UINT32*)(_p)) = (_v) )485#define SYMCRYPT_INTERNAL_VOLATILE_WRITE64( p, x ) { \486SYMCRYPT_INTERNAL_VOLATILE_WRITE32( &((PBYTE)p)[0], (UINT32)((x) ) );\487SYMCRYPT_INTERNAL_VOLATILE_WRITE32( &((PBYTE)p)[4], (UINT32)(((UINT64)(x))>>32) );\488}489#endif490491#else492493#error Unknown compiler494495#endif496497//498// FORCED MEMORY ACCESS499//500// These macros force a memory access. That is, they require that the memory501// read or write takes place, and do not allow the compiler to optimize the access502// away.503// They provide no other memory ordering requirements, so there are no acquire/release504// semantics, memory barriers, etc.505//506// The generic versions are implemented with a volatile access, but that is inefficient on some platforms507// because it might introduce memory ordering requirements.508//509510#define SYMCRYPT_INTERNAL_FORCE_READ8( _p ) SYMCRYPT_INTERNAL_VOLATILE_READ8( _p )511#define SYMCRYPT_INTERNAL_FORCE_READ16( _p ) SYMCRYPT_INTERNAL_VOLATILE_READ16( _p )512#define SYMCRYPT_INTERNAL_FORCE_READ32( _p ) SYMCRYPT_INTERNAL_VOLATILE_READ32( _p )513#define SYMCRYPT_INTERNAL_FORCE_READ64( _p ) SYMCRYPT_INTERNAL_VOLATILE_READ64( _p )514515#define SYMCRYPT_INTERNAL_FORCE_WRITE8( _p, _v ) SYMCRYPT_INTERNAL_VOLATILE_WRITE8( _p, _v )516#define SYMCRYPT_INTERNAL_FORCE_WRITE16( _p, _v ) SYMCRYPT_INTERNAL_VOLATILE_WRITE16( _p, _v )517#define SYMCRYPT_INTERNAL_FORCE_WRITE32( _p, _v ) SYMCRYPT_INTERNAL_VOLATILE_WRITE32( _p, _v )518#define SYMCRYPT_INTERNAL_FORCE_WRITE64( _p, _v ) SYMCRYPT_INTERNAL_VOLATILE_WRITE64( _p, _v )519520//521// FIXED ENDIANNESS ACCESS522//523// Fixed endianness load and store524// We do this by platform because it affected by both endianness and alignment requirements525// The p pointer is always a pointer to BYTE526//527#if SYMCRYPT_MS_VC // Microsoft VC++ Compiler528#define SYMCRYPT_BSWAP16( x ) _byteswap_ushort(x)529#define SYMCRYPT_BSWAP32( x ) _byteswap_ulong(x)530#define SYMCRYPT_BSWAP64( x ) _byteswap_uint64(x)531#elif SYMCRYPT_GNUC532#define SYMCRYPT_BSWAP16( x ) __builtin_bswap16(x)533#define SYMCRYPT_BSWAP32( x ) __builtin_bswap32(x)534#define SYMCRYPT_BSWAP64( x ) __builtin_bswap64(x)535#endif536537#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM64538539540//541// X86, AMD64, ARM, and ARM64 have no alignment restrictions, and are little-endian.542// We do straight store/loads with BSWAPs where required.543// This technically relies upon on undefined behavior, as we assume the compiler will translate544// operations on unaligned pointers to 2, 4, and 8 bytes types to appropriately unaligned store/load545// instructions on these platforms (not just in these macros). This works for all compilers we546// currently use.547//548#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST16( p ) SYMCRYPT_BSWAP16( *((UINT16 *)(p)) )549#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST16( p ) ( *((UINT16 *)(p)) )550#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST32( p ) SYMCRYPT_BSWAP32( *((UINT32 *)(p)) )551#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST32( p ) ( *((UINT32 *)(p)) )552#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST64( p ) SYMCRYPT_BSWAP64( *((UINT64 *)(p)) )553#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST64( p ) ( *((UINT64 *)(p)) )554555#define SYMCRYPT_INTERNAL_STORE_MSBFIRST16( p, x ) ( *(UINT16 *)(p) = SYMCRYPT_BSWAP16(x) )556#define SYMCRYPT_INTERNAL_STORE_LSBFIRST16( p, x ) ( *(UINT16 *)(p) = (x) )557#define SYMCRYPT_INTERNAL_STORE_MSBFIRST32( p, x ) ( *(UINT32 *)(p) = SYMCRYPT_BSWAP32(x) )558#define SYMCRYPT_INTERNAL_STORE_LSBFIRST32( p, x ) ( *(UINT32 *)(p) = (x) )559#define SYMCRYPT_INTERNAL_STORE_MSBFIRST64( p, x ) ( *(UINT64 *)(p) = SYMCRYPT_BSWAP64(x) )560#define SYMCRYPT_INTERNAL_STORE_LSBFIRST64( p, x ) ( *(UINT64 *)(p) = (x) )561562#elif SYMCRYPT_CPU_ARM563564//565// Only 64 bit accesses need to be aligned.566//567#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST16( p ) SYMCRYPT_BSWAP16( *((UINT16 *)(p)) )568#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST16( p ) ( *((UINT16 *)(p)) )569#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST32( p ) SYMCRYPT_BSWAP32( *((UINT32 *)(p)) )570#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST32( p ) ( *((UINT32 *)(p)) )571572#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST64( p ) ( (UINT64)SYMCRYPT_INTERNAL_LOAD_MSBFIRST32(&((PBYTE)p)[0]) << 32 | SYMCRYPT_INTERNAL_LOAD_MSBFIRST32(&((PBYTE)p)[4]) )573#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST64( p ) ( (UINT64)SYMCRYPT_INTERNAL_LOAD_LSBFIRST32(&((PBYTE)p)[4]) << 32 | SYMCRYPT_INTERNAL_LOAD_LSBFIRST32(&((PBYTE)p)[0]) )574575576577#define SYMCRYPT_INTERNAL_STORE_MSBFIRST16( p, x ) ( *(UINT16 *)(p) = SYMCRYPT_BSWAP16(x) )578#define SYMCRYPT_INTERNAL_STORE_LSBFIRST16( p, x ) ( *(UINT16 *)(p) = (x) )579#define SYMCRYPT_INTERNAL_STORE_MSBFIRST32( p, x ) ( *(UINT32 *)(p) = SYMCRYPT_BSWAP32(x) )580#define SYMCRYPT_INTERNAL_STORE_LSBFIRST32( p, x ) ( *(UINT32 *)(p) = (x) )581#define SYMCRYPT_INTERNAL_STORE_MSBFIRST64( p, x ) { \582SYMCRYPT_INTERNAL_STORE_MSBFIRST32( &((PBYTE)p)[0],(UINT32)(((UINT64)(x))>>32) );\583SYMCRYPT_INTERNAL_STORE_MSBFIRST32( &((PBYTE)p)[4],(UINT32)(x));\584}585586#define SYMCRYPT_INTERNAL_STORE_LSBFIRST64( p, x ) { \587SYMCRYPT_INTERNAL_STORE_LSBFIRST32( &((PBYTE)p)[0], (UINT32)((x) ) );\588SYMCRYPT_INTERNAL_STORE_LSBFIRST32( &((PBYTE)p)[4], (UINT32)(((UINT64)(x))>>32) );\589}590#else // unknown platform591592//593// These functions have to handle arbitrary alignments too, so we do them byte-by-byte in the594// generic case.595// So far these macros have not been fully tested596//597#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST16( p ) ( ((UINT16)((PBYTE)p)[0]) << 8 | ((PBYTE)p)[1] )598#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST16( p ) ( ((UINT16)((PBYTE)p)[1]) << 8 | ((PBYTE)p)[0] )599#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST32( p ) ( (UINT32)SYMCRYPT_INTERNAL_LOAD_MSBFIRST16(&((PBYTE)p)[0]) << 16 | SYMCRYPT_INTERNAL_LOAD_MSBFIRST16(&((PBYTE)p)[2]) )600#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST32( p ) ( (UINT32)SYMCRYPT_INTERNAL_LOAD_LSBFIRST16(&((PBYTE)p)[2]) << 16 | SYMCRYPT_INTERNAL_LOAD_LSBFIRST16(&((PBYTE)p)[0]) )601#define SYMCRYPT_INTERNAL_LOAD_MSBFIRST64( p ) ( (UINT64)SYMCRYPT_INTERNAL_LOAD_MSBFIRST32(&((PBYTE)p)[0]) << 32 | SYMCRYPT_INTERNAL_LOAD_MSBFIRST32(&((PBYTE)p)[4]) )602#define SYMCRYPT_INTERNAL_LOAD_LSBFIRST64( p ) ( (UINT64)SYMCRYPT_INTERNAL_LOAD_LSBFIRST32(&((PBYTE)p)[4]) << 32 | SYMCRYPT_INTERNAL_LOAD_LSBFIRST32(&((PBYTE)p)[0]) )603604#define SYMCRYPT_INTERNAL_STORE_MSBFIRST16( p, x ) { \605((PBYTE)p)[0] = (BYTE)((x)>> 8);\606((PBYTE)p)[1] = (BYTE)((x) );\607}608609#define SYMCRYPT_INTERNAL_STORE_LSBFIRST16( p, x ) { \610((PBYTE)p)[0] = (BYTE)((x) );\611((PBYTE)p)[1] = (BYTE)((x)>> 8);\612}613614#define SYMCRYPT_INTERNAL_STORE_MSBFIRST32( p, x ) { \615((PBYTE)p)[0] = (BYTE)((x)>>24);\616((PBYTE)p)[1] = (BYTE)((x)>>16);\617((PBYTE)p)[2] = (BYTE)((x)>> 8);\618((PBYTE)p)[3] = (BYTE)((x) );\619}620621#define SYMCRYPT_INTERNAL_STORE_LSBFIRST32( p, x ) { \622((PBYTE)p)[0] = (BYTE)((x) );\623((PBYTE)p)[1] = (BYTE)((x)>> 8);\624((PBYTE)p)[2] = (BYTE)((x)>>16);\625((PBYTE)p)[3] = (BYTE)((x)>>24);\626}627628#define SYMCRYPT_INTERNAL_STORE_MSBFIRST64( p, x ) { \629SYMCRYPT_INTERNAL_STORE_MSBFIRST32( &((PBYTE)p)[0],(UINT32)(((UINT64)(x))>>32) );\630SYMCRYPT_INTERNAL_STORE_MSBFIRST32( &((PBYTE)p)[4],(UINT32)(x));\631}632633#define SYMCRYPT_INTERNAL_STORE_LSBFIRST64( p, x ) { \634SYMCRYPT_INTERNAL_STORE_LSBFIRST32( &((PBYTE)p)[0], (UINT32)((x) ) );\635SYMCRYPT_INTERNAL_STORE_LSBFIRST32( &((PBYTE)p)[4], (UINT32)(((UINT64)(x))>>32) );\636}637638#endif // platform switch for load/store macros639640641//==============================================================================================642// INTERNAL DATA STRUCTURES643//==============================================================================================644//645// Note: we do not use the symbolic names like SYMCRYPT_SHA1_INPUT_BLOCK_SIZE as this646// file is included before that name is defined. Fixing that would make the public API header647// file harder to read by moving the constant away from the associated functions, or forcing648// the header file to use the struct name rather than the typedef. The current solution649// works quite well.650//651652//-----------------------------------------------------------------653// Block cipher description table654// Below are the typedefs for the block cipher description table type655// Callers can use this to define their own block cipher and use the block cipher656// modes.657//658659typedef struct _SYMCRYPT_BLOCKCIPHER SYMCRYPT_BLOCKCIPHER, *PSYMCRYPT_BLOCKCIPHER;660typedef const SYMCRYPT_BLOCKCIPHER * PCSYMCRYPT_BLOCKCIPHER;661662//663// Note that blockSize must be <= 32 and must be a power of two. This is true for all the block ciphers664// implemented in SymCrypt.665//666667//668// HASH STATES669//670// All hash states have the same basic structure. This allows all hash implementations to share671// the same buffer management code. Some algorithms might still have optimized buffer management code672// specific for their algorithm, but most algs use the generic code.673// This is especially important for parallel hashing, where the buffer management & parallel organizational674// code are tightly coupled.675//676677typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_COMMON_HASH_STATE678{679UINT32 bytesInBuffer;680SYMCRYPT_MAGIC_FIELD681UINT64 dataLengthL; // lower part of msg length682UINT64 dataLengthH; // upper part of msg length683SYMCRYPT_ALIGN BYTE buffer[SYMCRYPT_ANYSIZE_ARRAY]; // Size depends on algorithm684// ...685// Chaining state // type/location depends on algorithm686//687} SYMCRYPT_COMMON_HASH_STATE, *PSYMCRYPT_COMMON_HASH_STATE;688689690//691// SYMCRYPT_MD2_STATE692//693// Data structure that stores the state of an ongoing MD2 computation.694//695// The field names are from RFC 1319.696// It would be more efficient to store only the first 16 bytes of the X array,697// but that would complicate the code and MD2 isn't important enough to add698// extra complications.699//700typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD2_CHAINING_STATE701{702SYMCRYPT_ALIGN BYTE C[16]; // State for internal checksum computation703BYTE X[48]; // State for actual hash chaining704} SYMCRYPT_MD2_CHAINING_STATE, *PSYMCRYPT_MD2_CHAINING_STATE;705706//707// MD2 hash computation state.708//709typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD2_STATE710{711UINT32 bytesInBuffer;712SYMCRYPT_MAGIC_FIELD713UINT64 dataLengthL; // lower part of msg length714UINT64 dataLengthH; // upper part of msg length715SYMCRYPT_ALIGN BYTE buffer[16]; // buffer to keep one input block in716SYMCRYPT_MD2_CHAINING_STATE chain;717} SYMCRYPT_MD2_STATE, *PSYMCRYPT_MD2_STATE;718typedef const SYMCRYPT_MD2_STATE *PCSYMCRYPT_MD2_STATE;719720//721// SYMCRYPT_MD4_STATE722//723// Data structure that stores the state of an ongoing MD4 computation.724// The buffer contains dataLength % 64 bytes of data.725//726typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD4_CHAINING_STATE727{728UINT32 H[4];729} SYMCRYPT_MD4_CHAINING_STATE, *PSYMCRYPT_MD4_CHAINING_STATE;730731typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD4_STATE732{733UINT32 bytesInBuffer;734SYMCRYPT_MAGIC_FIELD735UINT64 dataLengthL; // lower part of msg length736UINT64 dataLengthH; // upper part of msg length737SYMCRYPT_ALIGN BYTE buffer[64]; // buffer to keep one input block in738SYMCRYPT_MD4_CHAINING_STATE chain; // chaining state739} SYMCRYPT_MD4_STATE, *PSYMCRYPT_MD4_STATE;740typedef const SYMCRYPT_MD4_STATE *PCSYMCRYPT_MD4_STATE;741742743//744// SYMCRYPT_MD5_STATE745//746// Data structure that stores the state of an ongoing MD5 computation.747// The buffer contains dataLength % 64 bytes of data.748//749typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD5_CHAINING_STATE750{751UINT32 H[4];752} SYMCRYPT_MD5_CHAINING_STATE, *PSYMCRYPT_MD5_CHAINING_STATE;753754755typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MD5_STATE756{757UINT32 bytesInBuffer;758SYMCRYPT_MAGIC_FIELD759UINT64 dataLengthL; // lower part of msg length760UINT64 dataLengthH; // upper part of msg length761SYMCRYPT_ALIGN BYTE buffer[64]; // buffer to keep one input block in762SYMCRYPT_MD5_CHAINING_STATE chain; // chaining state763} SYMCRYPT_MD5_STATE, *PSYMCRYPT_MD5_STATE;764typedef const SYMCRYPT_MD5_STATE *PCSYMCRYPT_MD5_STATE;765766767//768// SYMCRYPT_SHA1_STATE769//770// Data structure that stores the state of an ongoing SHA1 computation.771// The buffer contains dataLength % 64 bytes of data.772//773typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA1_CHAINING_STATE774{775UINT32 H[5];776} SYMCRYPT_SHA1_CHAINING_STATE, *PSYMCRYPT_SHA1_CHAINING_STATE;777778typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA1_STATE779{780UINT32 bytesInBuffer;781SYMCRYPT_MAGIC_FIELD782UINT64 dataLengthL; // lower part of msg length783UINT64 dataLengthH; // upper part of msg length784SYMCRYPT_ALIGN BYTE buffer[64]; // buffer to keep one input block in785SYMCRYPT_SHA1_CHAINING_STATE chain; // chaining state786} SYMCRYPT_SHA1_STATE, *PSYMCRYPT_SHA1_STATE;787typedef const SYMCRYPT_SHA1_STATE *PCSYMCRYPT_SHA1_STATE;788789790//791// SYMCRYPT_SHA256_STATE792//793// Data structure that stores the state of an ongoing SHA256 computation.794// The buffer contains dataLength % 64 bytes of data.795//796typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA256_CHAINING_STATE797{798SYMCRYPT_ALIGN UINT32 H[8];799} SYMCRYPT_SHA256_CHAINING_STATE, * PSYMCRYPT_SHA256_CHAINING_STATE;800801typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA256_STATE802{803UINT32 bytesInBuffer;804SYMCRYPT_MAGIC_FIELD805UINT64 dataLengthL; // lower part of msg length806UINT64 dataLengthH; // upper part of msg length807SYMCRYPT_ALIGN BYTE buffer[64]; // buffer to keep one input block in808SYMCRYPT_SHA256_CHAINING_STATE chain; // chaining state809} SYMCRYPT_SHA256_STATE, *PSYMCRYPT_SHA256_STATE;810typedef const SYMCRYPT_SHA256_STATE *PCSYMCRYPT_SHA256_STATE;811812813//814// SYMCRYPT_SHA224_STATE815//816// This is identical to the SHA256 state.817//818typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA224_STATE819{820UINT32 bytesInBuffer;821SYMCRYPT_MAGIC_FIELD822UINT64 dataLengthL; // lower part of msg length823UINT64 dataLengthH; // upper part of msg length824SYMCRYPT_ALIGN BYTE buffer[64]; // buffer to keep one input block in825SYMCRYPT_SHA256_CHAINING_STATE chain; // chaining state826} SYMCRYPT_SHA224_STATE, *PSYMCRYPT_SHA224_STATE;827typedef const SYMCRYPT_SHA224_STATE *PCSYMCRYPT_SHA224_STATE;828829830//831// SYMCRYPT_SHA512_STATE832//833// Data structure that stores the state of an ongoing SHA512 computation.834// The buffer contains dataLength % 128 bytes of data.835//836typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA512_CHAINING_STATE837{838UINT64 H[8];839} SYMCRYPT_SHA512_CHAINING_STATE, *PSYMCRYPT_SHA512_CHAINING_STATE;840841typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA512_STATE842{843UINT32 bytesInBuffer;844SYMCRYPT_MAGIC_FIELD845UINT64 dataLengthL; // lower part of msg length846UINT64 dataLengthH; // upper part of msg length847SYMCRYPT_ALIGN BYTE buffer[128]; // buffer to keep one input block in848SYMCRYPT_SHA512_CHAINING_STATE chain; // chaining state849} SYMCRYPT_SHA512_STATE, *PSYMCRYPT_SHA512_STATE;850typedef const SYMCRYPT_SHA512_STATE *PCSYMCRYPT_SHA512_STATE;851852853//854// SYMCRYPT_SHA384_STATE855//856// This is identical to the SHA512.857//858typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA384_STATE859{860UINT32 bytesInBuffer;861SYMCRYPT_MAGIC_FIELD862UINT64 dataLengthL; // lower part of msg length863UINT64 dataLengthH; // upper part of msg length864SYMCRYPT_ALIGN BYTE buffer[128]; // buffer to keep one input block in865SYMCRYPT_SHA512_CHAINING_STATE chain; // chaining state866} SYMCRYPT_SHA384_STATE, *PSYMCRYPT_SHA384_STATE;867typedef const SYMCRYPT_SHA384_STATE *PCSYMCRYPT_SHA384_STATE;868869870//871// SYMCRYPT_SHA512_224_STATE872//873// This is identical to the SHA512.874//875typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA512_224_STATE876{877UINT32 bytesInBuffer;878SYMCRYPT_MAGIC_FIELD879UINT64 dataLengthL; // lower part of msg length880UINT64 dataLengthH; // upper part of msg length881SYMCRYPT_ALIGN BYTE buffer[128]; // buffer to keep one input block in882SYMCRYPT_SHA512_CHAINING_STATE chain; // chaining state883} SYMCRYPT_SHA512_224_STATE, *PSYMCRYPT_SHA512_224_STATE;884typedef const SYMCRYPT_SHA512_224_STATE *PCSYMCRYPT_SHA512_224_STATE;885886887//888// SYMCRYPT_SHA512_256_STATE889//890// This is identical to the SHA512.891//892typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA512_256_STATE893{894UINT32 bytesInBuffer;895SYMCRYPT_MAGIC_FIELD896UINT64 dataLengthL; // lower part of msg length897UINT64 dataLengthH; // upper part of msg length898SYMCRYPT_ALIGN BYTE buffer[128]; // buffer to keep one input block in899SYMCRYPT_SHA512_CHAINING_STATE chain; // chaining state900} SYMCRYPT_SHA512_256_STATE, *PSYMCRYPT_SHA512_256_STATE;901typedef const SYMCRYPT_SHA512_256_STATE *PCSYMCRYPT_SHA512_256_STATE;902903904//905// SYMCRYPT_KECCAK_STATE906//907// Data structure that stores the state of an ongoing SHA-3 derived algorithm computation.908//909910typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_KECCAK_STATE911{912SYMCRYPT_ALIGN UINT64 state[25]; // state for Keccak-f[1600] permutation913UINT32 inputBlockSize; // rate914UINT32 stateIndex; // position in the state for next merge/extract operation915UINT8 paddingValue; // Keccak padding value916BOOLEAN squeezeMode; // denotes whether the state is in squeeze mode917} SYMCRYPT_KECCAK_STATE, *PSYMCRYPT_KECCAK_STATE;918typedef const SYMCRYPT_KECCAK_STATE *PCSYMCRYPT_KECCAK_STATE;919920//921// SYMCRYPT_SHA3_224_STATE922//923// Data structure that stores the state of an ongoing SHA3-224 computation.924//925typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA3_224_STATE926{927SYMCRYPT_KECCAK_STATE ks;928SYMCRYPT_MAGIC_FIELD929} SYMCRYPT_SHA3_224_STATE, * PSYMCRYPT_SHA3_224_STATE;930typedef const SYMCRYPT_SHA3_224_STATE* PCSYMCRYPT_SHA3_224_STATE;931932//933// SYMCRYPT_SHA3_256_STATE934//935// Data structure that stores the state of an ongoing SHA3-256 computation.936//937typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA3_256_STATE938{939SYMCRYPT_KECCAK_STATE ks;940SYMCRYPT_MAGIC_FIELD941} SYMCRYPT_SHA3_256_STATE, * PSYMCRYPT_SHA3_256_STATE;942typedef const SYMCRYPT_SHA3_256_STATE* PCSYMCRYPT_SHA3_256_STATE;943944//945// SYMCRYPT_SHA3_384_STATE946//947// Data structure that stores the state of an ongoing SHA3-384 computation.948//949typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA3_384_STATE950{951SYMCRYPT_KECCAK_STATE ks;952SYMCRYPT_MAGIC_FIELD953} SYMCRYPT_SHA3_384_STATE, * PSYMCRYPT_SHA3_384_STATE;954typedef const SYMCRYPT_SHA3_384_STATE* PCSYMCRYPT_SHA3_384_STATE;955956//957// SYMCRYPT_SHA3_512_STATE958//959// Data structure that stores the state of an ongoing SHA3-512 computation.960//961typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHA3_512_STATE962{963SYMCRYPT_KECCAK_STATE ks;964SYMCRYPT_MAGIC_FIELD965} SYMCRYPT_SHA3_512_STATE, * PSYMCRYPT_SHA3_512_STATE;966typedef const SYMCRYPT_SHA3_512_STATE* PCSYMCRYPT_SHA3_512_STATE;967968//969// SYMCRYPT_SHAKE128_STATE970//971// Data structure that stores the state of an ongoing SHAKE128 computation.972//973typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHAKE128_STATE974{975SYMCRYPT_KECCAK_STATE ks;976SYMCRYPT_MAGIC_FIELD977} SYMCRYPT_SHAKE128_STATE, * PSYMCRYPT_SHAKE128_STATE;978typedef const SYMCRYPT_SHAKE128_STATE* PCSYMCRYPT_SHAKE128_STATE;979980//981// SYMCRYPT_SHAKE256_STATE982//983// Data structure that stores the state of an ongoing SHAKE256 computation.984//985typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_SHAKE256_STATE986{987SYMCRYPT_KECCAK_STATE ks;988SYMCRYPT_MAGIC_FIELD989} SYMCRYPT_SHAKE256_STATE, * PSYMCRYPT_SHAKE256_STATE;990typedef const SYMCRYPT_SHAKE256_STATE* PCSYMCRYPT_SHAKE256_STATE;991992//993// SYMCRYPT_CSHAKE128_STATE994//995// Data structure that stores the state of an ongoing CSHAKE128 computation.996//997typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_CSHAKE128_STATE998{999SYMCRYPT_KECCAK_STATE ks;1000SYMCRYPT_MAGIC_FIELD1001} SYMCRYPT_CSHAKE128_STATE, * PSYMCRYPT_CSHAKE128_STATE;1002typedef const SYMCRYPT_CSHAKE128_STATE* PCSYMCRYPT_CSHAKE128_STATE;10031004//1005// SYMCRYPT_CSHAKE256_STATE1006//1007// Data structure that stores the state of an ongoing CSHAKE256 computation.1008//1009typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_CSHAKE256_STATE1010{1011SYMCRYPT_KECCAK_STATE ks;1012SYMCRYPT_MAGIC_FIELD1013} SYMCRYPT_CSHAKE256_STATE, * PSYMCRYPT_CSHAKE256_STATE;1014typedef const SYMCRYPT_CSHAKE256_STATE* PCSYMCRYPT_CSHAKE256_STATE;10151016//1017// SYMCRYPT_KMAC128_EXPANDED_KEY1018//1019// Data structure that stores the expanded key for KMAC128.1020//1021typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_KMAC128_EXPANDED_KEY1022{1023SYMCRYPT_KECCAK_STATE ks;1024SYMCRYPT_MAGIC_FIELD1025} SYMCRYPT_KMAC128_EXPANDED_KEY, * PSYMCRYPT_KMAC128_EXPANDED_KEY;1026typedef const SYMCRYPT_KMAC128_EXPANDED_KEY* PCSYMCRYPT_KMAC128_EXPANDED_KEY;10271028//1029// SYMCRYPT_KMAC128_STATE1030//1031// Data structure that stores the state of an ongoing KMAC128 computation.1032//1033typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_KMAC128_STATE1034{1035SYMCRYPT_KECCAK_STATE ks;1036SYMCRYPT_MAGIC_FIELD1037} SYMCRYPT_KMAC128_STATE, * PSYMCRYPT_KMAC128_STATE;1038typedef const SYMCRYPT_KMAC128_STATE* PCSYMCRYPT_KMAC128_STATE;10391040//1041// SYMCRYPT_KMAC256_EXPANDED_KEY1042//1043// Data structure that stores the expanded key for KMAC256.1044//1045typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_KMAC256_EXPANDED_KEY1046{1047SYMCRYPT_KECCAK_STATE ks;1048SYMCRYPT_MAGIC_FIELD1049} SYMCRYPT_KMAC256_EXPANDED_KEY, * PSYMCRYPT_KMAC256_EXPANDED_KEY;1050typedef const SYMCRYPT_KMAC256_EXPANDED_KEY* PCSYMCRYPT_KMAC256_EXPANDED_KEY;10511052//1053// SYMCRYPT_KMAC256_STATE1054//1055// Data structure that stores the state of an ongoing KMAC256 computation.1056//1057typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_KMAC256_STATE1058{1059SYMCRYPT_KECCAK_STATE ks;1060SYMCRYPT_MAGIC_FIELD1061} SYMCRYPT_KMAC256_STATE, * PSYMCRYPT_KMAC256_STATE;1062typedef const SYMCRYPT_KMAC256_STATE* PCSYMCRYPT_KMAC256_STATE;106310641065//1066// Generic hashing1067//10681069typedef struct _SYMCRYPT_OID {1070UINT32 cbOID;1071_Field_size_( cbOID ) PCBYTE pbOID;1072} SYMCRYPT_OID, *PSYMCRYPT_OID;1073typedef const SYMCRYPT_OID *PCSYMCRYPT_OID;10741075//1076// OID lists for the most commonly used hash functions1077//10781079#define SYMCRYPT_MD5_OID_COUNT (2)1080extern const SYMCRYPT_OID SymCryptMd5OidList[SYMCRYPT_MD5_OID_COUNT];10811082#define SYMCRYPT_SHA1_OID_COUNT (2)1083extern const SYMCRYPT_OID SymCryptSha1OidList[SYMCRYPT_SHA1_OID_COUNT];10841085#define SYMCRYPT_SHA224_OID_COUNT (2)1086extern const SYMCRYPT_OID SymCryptSha224OidList[SYMCRYPT_SHA224_OID_COUNT];10871088#define SYMCRYPT_SHA256_OID_COUNT (2)1089extern const SYMCRYPT_OID SymCryptSha256OidList[SYMCRYPT_SHA256_OID_COUNT];10901091#define SYMCRYPT_SHA384_OID_COUNT (2)1092extern const SYMCRYPT_OID SymCryptSha384OidList[SYMCRYPT_SHA384_OID_COUNT];10931094#define SYMCRYPT_SHA512_OID_COUNT (2)1095extern const SYMCRYPT_OID SymCryptSha512OidList[SYMCRYPT_SHA512_OID_COUNT];10961097#define SYMCRYPT_SHA512_224_OID_COUNT (2)1098extern const SYMCRYPT_OID SymCryptSha512_224OidList[SYMCRYPT_SHA512_224_OID_COUNT];10991100#define SYMCRYPT_SHA512_256_OID_COUNT (2)1101extern const SYMCRYPT_OID SymCryptSha512_256OidList[SYMCRYPT_SHA512_256_OID_COUNT];11021103#define SYMCRYPT_SHA3_224_OID_COUNT (2)1104extern const SYMCRYPT_OID SymCryptSha3_224OidList[SYMCRYPT_SHA3_224_OID_COUNT];11051106#define SYMCRYPT_SHA3_256_OID_COUNT (2)1107extern const SYMCRYPT_OID SymCryptSha3_256OidList[SYMCRYPT_SHA3_256_OID_COUNT];11081109#define SYMCRYPT_SHA3_384_OID_COUNT (2)1110extern const SYMCRYPT_OID SymCryptSha3_384OidList[SYMCRYPT_SHA3_384_OID_COUNT];11111112#define SYMCRYPT_SHA3_512_OID_COUNT (2)1113extern const SYMCRYPT_OID SymCryptSha3_512OidList[SYMCRYPT_SHA3_512_OID_COUNT];11141115#define SYMCRYPT_SHAKE128_OID_COUNT (2)1116extern const SYMCRYPT_OID SymCryptShake128OidList[SYMCRYPT_SHAKE128_OID_COUNT];11171118#define SYMCRYPT_SHAKE256_OID_COUNT (2)1119extern const SYMCRYPT_OID SymCryptShake256OidList[SYMCRYPT_SHAKE256_OID_COUNT];11201121typedef enum _SYMCRYPT_OID_LIST_ID1122{1123SYMCRYPT_OID_LIST_ID_NULL = 0,1124SYMCRYPT_OID_LIST_ID_MD5 = 1,1125SYMCRYPT_OID_LIST_ID_SHA1 = 2,1126SYMCRYPT_OID_LIST_ID_SHA224 = 3,1127SYMCRYPT_OID_LIST_ID_SHA256 = 4,1128SYMCRYPT_OID_LIST_ID_SHA384 = 5,1129SYMCRYPT_OID_LIST_ID_SHA512 = 6,1130SYMCRYPT_OID_LIST_ID_SHA512_224 = 7,1131SYMCRYPT_OID_LIST_ID_SHA512_256 = 8,1132SYMCRYPT_OID_LIST_ID_SHA3_224 = 9,1133SYMCRYPT_OID_LIST_ID_SHA3_256 = 10,1134SYMCRYPT_OID_LIST_ID_SHA3_384 = 11,1135SYMCRYPT_OID_LIST_ID_SHA3_512 = 12,1136SYMCRYPT_OID_LIST_ID_SHAKE128 = 13,1137SYMCRYPT_OID_LIST_ID_SHAKE256 = 141138} SYMCRYPT_OID_LIST_ID;11391140PCSYMCRYPT_OID1141SYMCRYPT_CALL1142SymCryptGetOidList( SYMCRYPT_OID_LIST_ID oidId, _Out_opt_ SIZE_T* pCount );1143//1144// Returns a pointer to the OID list for the specified OID list ID. If pCount is non-NULL, the1145// pointed-to value will be set to the number of elements in the OID list.1146// Returns NULL if the OID list ID is invalid.1147//11481149typedef union _SYMCRYPT_HASH_STATE1150{1151SYMCRYPT_MD2_STATE md2State;1152SYMCRYPT_MD4_STATE md4State;1153SYMCRYPT_MD5_STATE md5State;1154SYMCRYPT_SHA1_STATE sha1State;1155SYMCRYPT_SHA224_STATE sha224State;1156SYMCRYPT_SHA256_STATE sha256State;1157SYMCRYPT_SHA384_STATE sha384State;1158SYMCRYPT_SHA512_STATE sha512State;1159SYMCRYPT_SHA512_224_STATE sha512_224State;1160SYMCRYPT_SHA512_256_STATE sha512_256State;1161SYMCRYPT_SHA3_224_STATE sha3_224State;1162SYMCRYPT_SHA3_256_STATE sha3_256State;1163SYMCRYPT_SHA3_384_STATE sha3_384State;1164SYMCRYPT_SHA3_512_STATE sha3_512State;1165} SYMCRYPT_HASH_STATE, *PSYMCRYPT_HASH_STATE;1166typedef const SYMCRYPT_HASH_STATE *PCSYMCRYPT_HASH_STATE;11671168#define SYMCRYPT_HASH_MAX_RESULT_SIZE SYMCRYPT_SHA512_RESULT_SIZE11691170SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HASH;1171SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_PARALLEL_HASH;11721173typedef struct _SYMCRYPT_HASH SYMCRYPT_HASH, *PSYMCRYPT_HASH;1174typedef const SYMCRYPT_HASH *PCSYMCRYPT_HASH;1175typedef struct _SYMCRYPT_PARALLEL_HASH SYMCRYPT_PARALLEL_HASH, *PSYMCRYPT_PARALLEL_HASH;1176typedef const SYMCRYPT_PARALLEL_HASH *PCSYMCRYPT_PARALLEL_HASH;11771178typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_INIT_FUNC) ( PVOID pState );1179typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_APPEND_FUNC) ( PVOID pState, PCBYTE pbData, SIZE_T cbData );1180typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_RESULT_FUNC) ( PVOID pState, PVOID pbResult );1181typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_APPEND_BLOCKS_FUNC) ( PVOID pChain, PCBYTE pbData, SIZE_T cbData, SIZE_T * pcbRemaining );1182typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_HASH_STATE_COPY_FUNC) ( PCVOID pStateSrc, PVOID pStateDst );11831184typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HASH1185{1186PSYMCRYPT_HASH_INIT_FUNC initFunc;1187PSYMCRYPT_HASH_APPEND_FUNC appendFunc;1188PSYMCRYPT_HASH_RESULT_FUNC resultFunc;1189PSYMCRYPT_HASH_APPEND_BLOCKS_FUNC appendBlockFunc;1190PSYMCRYPT_HASH_STATE_COPY_FUNC stateCopyFunc;1191UINT32 stateSize; // sizeof( hash state )1192UINT32 resultSize; // size of hash result1193UINT32 inputBlockSize;1194UINT32 chainOffset; // offset into state structure of the chaining state1195UINT32 chainSize; // size of chaining state1196} SYMCRYPT_HASH, *PSYMCRYPT_HASH;119711981199//1200// Parallel hashing1201//12021203#if SYMCRYPT_CPU_ARM1204#define SYMCRYPT_PARALLEL_SHA256_MIN_PARALLELISM (3)1205#define SYMCRYPT_PARALLEL_SHA256_MAX_PARALLELISM (4)1206#else1207#define SYMCRYPT_PARALLEL_SHA256_MIN_PARALLELISM (2)1208#define SYMCRYPT_PARALLEL_SHA256_MAX_PARALLELISM (8)1209#endif12101211typedef enum _SYMCRYPT_HASH_OPERATION_TYPE {1212SYMCRYPT_HASH_OPERATION_APPEND = 1,1213SYMCRYPT_HASH_OPERATION_RESULT = 2,1214} SYMCRYPT_HASH_OPERATION_TYPE;12151216typedef struct _SYMCRYPT_PARALLEL_HASH_OPERATION SYMCRYPT_PARALLEL_HASH_OPERATION, *PSYMCRYPT_PARALLEL_HASH_OPERATION;1217typedef const SYMCRYPT_PARALLEL_HASH_OPERATION *PCSYMRYPT_PARALLEL_HASH_OPERATION;12181219struct _SYMCRYPT_PARALLEL_HASH_OPERATION {1220SIZE_T iHash; // index of hash object into the state array1221SYMCRYPT_HASH_OPERATION_TYPE hashOperation; // operation to be performed1222_Field_size_( cbBuffer ) PBYTE pbBuffer; // data to be hashed, or result buffer1223SIZE_T cbBuffer; // size of pbData buffer.1224PSYMCRYPT_PARALLEL_HASH_OPERATION next; // internal scratch space; do not use.1225};122612271228SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_PARALLEL_HASH_SCRATCH_OPERATION; // as yet unspecified struct1229typedef struct _SYMCRYPT_PARALLEL_HASH_SCRATCH_OPERATION1230SYMCRYPT_PARALLEL_HASH_SCRATCH_OPERATION, *PSYMCRYPT_PARALLEL_HASH_SCRATCH_OPERATION;12311232typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_PARALLEL_HASH_SCRATCH_STATE {1233PVOID hashState; // the actual hash state1234BYTE processingState;1235BYTE bytesAlreadyProcessed; // of the next Append operation1236UINT64 bytes; // # bytes left to process on this state1237PSYMCRYPT_PARALLEL_HASH_OPERATION next; // next operation to be performed.1238PCBYTE pbData; // data/size of ongoing append operation; this op has already been removed from the next linked list1239SIZE_T cbData;1240}SYMCRYPT_PARALLEL_HASH_SCRATCH_STATE, *PSYMCRYPT_PARALLEL_HASH_SCRATCH_STATE;124112421243//1244// The scratch space used by parallel SHA-256 consists of three regions:1245// - an array of SYMCRYPT_PARALLEL_HASH_SCRATCH_STATE structures, aligned to SYMCRYPT_ALIGN_VALUE.1246// - the work array, an array of pointers to SYMCRYPT_PARALLEL_HASH_SCRATCH_STATEs.1247// - an array of 4 + 8 + 64 SIMD vector elements, aligned to the size of those elements.1248//1249//1250#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD641251#define SYMCRYPT_SIMD_ELEMENT_SIZE 321252#elif SYMCRYPT_CPU_ARM | SYMCRYPT_CPU_ARM641253#define SYMCRYPT_SIMD_ELEMENT_SIZE 161254#elif SYMCRYPT_CPU_UNKNOWN1255#define SYMCRYPT_SIMD_ELEMENT_SIZE 01256#else1257#error Unknown CPU1258#endif12591260#define SYMCRYPT_PARALLEL_SHA256_FIXED_SCRATCH ( (4 + 8 + 64) * SYMCRYPT_SIMD_ELEMENT_SIZE + SYMCRYPT_SIMD_ELEMENT_SIZE - 1 + SYMCRYPT_ALIGN_VALUE - 1 )1261#define SYMCRYPT_PARALLEL_SHA384_FIXED_SCRATCH ( (4 + 8 + 80) * SYMCRYPT_SIMD_ELEMENT_SIZE + SYMCRYPT_SIMD_ELEMENT_SIZE - 1 + SYMCRYPT_ALIGN_VALUE - 1 )1262#define SYMCRYPT_PARALLEL_SHA512_FIXED_SCRATCH ( (4 + 8 + 80) * SYMCRYPT_SIMD_ELEMENT_SIZE + SYMCRYPT_SIMD_ELEMENT_SIZE - 1 + SYMCRYPT_ALIGN_VALUE - 1 )1263#define SYMCRYPT_PARALLEL_HASH_PER_STATE_SCRATCH (sizeof( SYMCRYPT_PARALLEL_HASH_SCRATCH_STATE ) + sizeof( PSYMCRYPT_PARALLEL_HASH_SCRATCH_STATE ) )12641265SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_PARALLEL_HASH;1266typedef struct _SYMCRYPT_PARALLEL_HASH SYMCRYPT_PARALLEL_HASH, *PSYMCRYPT_PARALLEL_HASH;1267typedef const SYMCRYPT_PARALLEL_HASH *PCSYMCRYPT_PARALLEL_HASH;12681269typedef 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 );1270typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_PARALLEL_HASH_RESULT_DONE_FUNC ) (PCSYMCRYPT_PARALLEL_HASH pParHash, PSYMCRYPT_COMMON_HASH_STATE pState, PCSYMRYPT_PARALLEL_HASH_OPERATION pOp);1271typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_PARALLEL_APPEND_FUNC) (1272_Inout_updates_( nPar ) PSYMCRYPT_PARALLEL_HASH_SCRATCH_STATE * pWork,1273SIZE_T nPar,1274SIZE_T nBytes,1275_Out_writes_( cbSimdScratch ) PBYTE pbSimdScratch,1276SIZE_T cbSimdScratch );12771278typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_PARALLEL_HASH1279{1280PCSYMCRYPT_HASH pHash;1281UINT32 parScratchFixed; // fixed scratch size for parallel hash1282PSYMCRYPT_PARALLEL_HASH_RESULT_FUNC parResult1Func;1283PSYMCRYPT_PARALLEL_HASH_RESULT_FUNC parResult2Func;1284PSYMCRYPT_PARALLEL_HASH_RESULT_DONE_FUNC parResultDoneFunc;12851286PSYMCRYPT_PARALLEL_APPEND_FUNC parAppendFunc;1287} SYMCRYPT_PARALLEL_HASH, *PSYMCRYPT_PARALLEL_HASH;128812891290//======================================================================================================1291// MAC1292//129312941295//1296// SYMCRYPT_HMAC_MD5_EXPANDED_KEY1297//1298// Data structure to store an expanded key for HMAC-MD5.1299//1300typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_MD5_EXPANDED_KEY1301{1302SYMCRYPT_MD5_CHAINING_STATE innerState;1303SYMCRYPT_MD5_CHAINING_STATE outerState;1304SYMCRYPT_MAGIC_FIELD1305} SYMCRYPT_HMAC_MD5_EXPANDED_KEY, *PSYMCRYPT_HMAC_MD5_EXPANDED_KEY;1306typedef const SYMCRYPT_HMAC_MD5_EXPANDED_KEY * PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY;13071308//1309// SYMCRYPT_HMAC_MD5_STATE1310//1311// Data structure that encodes an ongoing HMAC-MD5 computation.1312//1313typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_MD5_STATE1314{1315SYMCRYPT_MD5_STATE hash;1316PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY pKey;1317SYMCRYPT_MAGIC_FIELD1318} SYMCRYPT_HMAC_MD5_STATE, *PSYMCRYPT_HMAC_MD5_STATE;1319typedef const SYMCRYPT_HMAC_MD5_STATE *PCSYMCRYPT_HMAC_MD5_STATE;132013211322//1323// SYMCRYPT_HMAC_SHA1_EXPANDED_KEY1324//1325// Data structure to store an expanded key for HMAC-SHA1.1326//1327typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA1_EXPANDED_KEY1328{1329SYMCRYPT_SHA1_CHAINING_STATE innerState;1330SYMCRYPT_SHA1_CHAINING_STATE outerState;1331SYMCRYPT_MAGIC_FIELD1332} SYMCRYPT_HMAC_SHA1_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA1_EXPANDED_KEY;1333typedef const SYMCRYPT_HMAC_SHA1_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA1_EXPANDED_KEY;13341335//1336// SYMCRYPT_HMAC_SHA1_STATE1337//1338// Data structure that encodes an ongoing HMAC-SHA1 computation.1339//1340typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA1_STATE1341{1342SYMCRYPT_SHA1_STATE hash;1343PCSYMCRYPT_HMAC_SHA1_EXPANDED_KEY pKey;1344SYMCRYPT_MAGIC_FIELD1345} SYMCRYPT_HMAC_SHA1_STATE, *PSYMCRYPT_HMAC_SHA1_STATE;1346typedef const SYMCRYPT_HMAC_SHA1_STATE *PCSYMCRYPT_HMAC_SHA1_STATE;134713481349//1350// SYMCRYPT_HMAC_SHA224_EXPANDED_KEY1351//1352// Data structure to store an expanded key for HMAC-SHA224.1353//1354typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA224_EXPANDED_KEY1355{1356SYMCRYPT_SHA256_CHAINING_STATE innerState;1357SYMCRYPT_SHA256_CHAINING_STATE outerState;1358SYMCRYPT_MAGIC_FIELD1359} SYMCRYPT_HMAC_SHA224_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA224_EXPANDED_KEY;1360typedef const SYMCRYPT_HMAC_SHA224_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA224_EXPANDED_KEY;13611362//1363// SYMCRYPT_HMAC_SHA224_STATE1364//1365// Data structure that encodes an ongoing HMAC-SHA224 computation.1366//1367typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA224_STATE1368{1369SYMCRYPT_SHA224_STATE hash;1370PCSYMCRYPT_HMAC_SHA224_EXPANDED_KEY pKey;1371SYMCRYPT_MAGIC_FIELD1372} SYMCRYPT_HMAC_SHA224_STATE, *PSYMCRYPT_HMAC_SHA224_STATE;1373typedef const SYMCRYPT_HMAC_SHA224_STATE *PCSYMCRYPT_HMAC_SHA224_STATE;137413751376//1377// SYMCRYPT_HMAC_SHA256_EXPANDED_KEY1378//1379// Data structure to store an expanded key for HMAC-SHA256.1380//1381typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA256_EXPANDED_KEY1382{1383SYMCRYPT_SHA256_CHAINING_STATE innerState;1384SYMCRYPT_SHA256_CHAINING_STATE outerState;1385SYMCRYPT_MAGIC_FIELD1386} SYMCRYPT_HMAC_SHA256_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA256_EXPANDED_KEY;1387typedef const SYMCRYPT_HMAC_SHA256_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA256_EXPANDED_KEY;13881389//1390// SYMCRYPT_HMAC_SHA256_STATE1391//1392// Data structure that encodes an ongoing HMAC-SHA256 computation.1393//1394typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA256_STATE1395{1396SYMCRYPT_SHA256_STATE hash;1397PCSYMCRYPT_HMAC_SHA256_EXPANDED_KEY pKey;1398SYMCRYPT_MAGIC_FIELD1399} SYMCRYPT_HMAC_SHA256_STATE, *PSYMCRYPT_HMAC_SHA256_STATE;1400typedef const SYMCRYPT_HMAC_SHA256_STATE *PCSYMCRYPT_HMAC_SHA256_STATE;140114021403//1404// SYMCRYPT_HMAC_SHA384_EXPANDED_KEY1405//1406// Data structure to store an expanded key for HMAC-SHA384.1407//1408typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA384_EXPANDED_KEY1409{1410SYMCRYPT_SHA512_CHAINING_STATE innerState;1411SYMCRYPT_SHA512_CHAINING_STATE outerState;1412SYMCRYPT_MAGIC_FIELD1413} SYMCRYPT_HMAC_SHA384_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA384_EXPANDED_KEY;1414typedef const SYMCRYPT_HMAC_SHA384_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA384_EXPANDED_KEY;14151416//1417// SYMCRYPT_HMAC_SHA384_STATE1418//1419// Data structure that encodes an ongoing HMAC-SHA384 computation.1420//1421typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA384_STATE1422{1423SYMCRYPT_SHA384_STATE hash;1424PCSYMCRYPT_HMAC_SHA384_EXPANDED_KEY pKey;1425SYMCRYPT_MAGIC_FIELD1426} SYMCRYPT_HMAC_SHA384_STATE, *PSYMCRYPT_HMAC_SHA384_STATE;1427typedef const SYMCRYPT_HMAC_SHA384_STATE *PCSYMCRYPT_HMAC_SHA384_STATE;14281429//1430// SYMCRYPT_HMAC_SHA512_EXPANDED_KEY1431//1432// Data structure to store an expanded key for HMAC-SHA512.1433//1434typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA512_EXPANDED_KEY1435{1436SYMCRYPT_SHA512_CHAINING_STATE innerState;1437SYMCRYPT_SHA512_CHAINING_STATE outerState;1438SYMCRYPT_MAGIC_FIELD1439} SYMCRYPT_HMAC_SHA512_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA512_EXPANDED_KEY;1440typedef const SYMCRYPT_HMAC_SHA512_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA512_EXPANDED_KEY;14411442//1443// SYMCRYPT_HMAC_SHA512_STATE1444//1445// Data structure that encodes an ongoing HMAC-SHA512 computation.1446//1447typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA512_STATE1448{1449SYMCRYPT_SHA512_STATE hash;1450PCSYMCRYPT_HMAC_SHA512_EXPANDED_KEY pKey;1451SYMCRYPT_MAGIC_FIELD1452} SYMCRYPT_HMAC_SHA512_STATE, *PSYMCRYPT_HMAC_SHA512_STATE;1453typedef const SYMCRYPT_HMAC_SHA512_STATE *PCSYMCRYPT_HMAC_SHA512_STATE;14541455//1456// SYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY1457//1458// Data structure to store an expanded key for HMAC-SHA512_224.1459//1460typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY1461{1462SYMCRYPT_SHA512_CHAINING_STATE innerState;1463SYMCRYPT_SHA512_CHAINING_STATE outerState;1464SYMCRYPT_MAGIC_FIELD1465} SYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY;1466typedef const SYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY;14671468//1469// SYMCRYPT_HMAC_SHA512_224_STATE1470//1471// Data structure that encodes an ongoing HMAC-SHA512_224 computation.1472//1473typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA512_224_STATE1474{1475SYMCRYPT_SHA512_224_STATE hash;1476PCSYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY pKey;1477SYMCRYPT_MAGIC_FIELD1478} SYMCRYPT_HMAC_SHA512_224_STATE, *PSYMCRYPT_HMAC_SHA512_224_STATE;1479typedef const SYMCRYPT_HMAC_SHA512_224_STATE *PCSYMCRYPT_HMAC_SHA512_224_STATE;14801481//1482// SYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY1483//1484// Data structure to store an expanded key for HMAC-SHA512_256.1485//1486typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY1487{1488SYMCRYPT_SHA512_CHAINING_STATE innerState;1489SYMCRYPT_SHA512_CHAINING_STATE outerState;1490SYMCRYPT_MAGIC_FIELD1491} SYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY;1492typedef const SYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY;14931494//1495// SYMCRYPT_HMAC_SHA512_256_STATE1496//1497// Data structure that encodes an ongoing HMAC-SHA512_256 computation.1498//1499typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA512_256_STATE1500{1501SYMCRYPT_SHA512_256_STATE hash;1502PCSYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY pKey;1503SYMCRYPT_MAGIC_FIELD1504} SYMCRYPT_HMAC_SHA512_256_STATE, *PSYMCRYPT_HMAC_SHA512_256_STATE;1505typedef const SYMCRYPT_HMAC_SHA512_256_STATE *PCSYMCRYPT_HMAC_SHA512_256_STATE;15061507//1508// SYMCRYPT_HMAC_EXPANDED_KEY1509//1510// Generic HMAC Expanded Key data structure1511//1512typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_EXPANDED_KEY1513{1514PCSYMCRYPT_HASH pHash;1515SYMCRYPT_HASH_STATE innerState;1516SYMCRYPT_HASH_STATE outerState;1517SYMCRYPT_MAGIC_FIELD1518} SYMCRYPT_HMAC_EXPANDED_KEY, * PSYMCRYPT_HMAC_EXPANDED_KEY;1519typedef const SYMCRYPT_HMAC_EXPANDED_KEY* PCSYMCRYPT_HMAC_EXPANDED_KEY;15201521//1522// SYMCRYPT_HMAC_STATE1523//1524// Generic HMAC data structure1525//1526typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_STATE1527{1528PCSYMCRYPT_HMAC_EXPANDED_KEY pKey;1529SYMCRYPT_HASH_STATE hash;1530SYMCRYPT_MAGIC_FIELD1531} SYMCRYPT_HMAC_STATE, * PSYMCRYPT_HMAC_STATE;1532typedef const SYMCRYPT_HMAC_STATE* PCSYMCRYPT_HMAC_STATE;15331534//1535// SYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY1536//1537// Data structure to store an expanded key for HMAC-SHA3-2241538//1539typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY1540{1541SYMCRYPT_HMAC_EXPANDED_KEY generic;15421543} SYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY;1544typedef const SYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY;15451546//1547// SYMCRYPT_HMAC_SHA3_224_STATE1548//1549// Data structure that encodes an ongoing HMAC-SHA3-224 computation.1550//1551typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_224_STATE1552{1553SYMCRYPT_HMAC_STATE generic;15541555} SYMCRYPT_HMAC_SHA3_224_STATE, *PSYMCRYPT_HMAC_SHA3_224_STATE;1556typedef const SYMCRYPT_HMAC_SHA3_224_STATE *PCSYMCRYPT_HMAC_SHA3_224_STATE;15571558//1559// SYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY1560//1561// Data structure to store an expanded key for HMAC-SHA3-2561562//1563typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY1564{1565SYMCRYPT_HMAC_EXPANDED_KEY generic;15661567} SYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY;1568typedef const SYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY;15691570//1571// SYMCRYPT_HMAC_SHA3_256_STATE1572//1573// Data structure that encodes an ongoing HMAC-SHA3-256 computation.1574//1575typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_256_STATE1576{1577SYMCRYPT_HMAC_STATE generic;15781579} SYMCRYPT_HMAC_SHA3_256_STATE, *PSYMCRYPT_HMAC_SHA3_256_STATE;1580typedef const SYMCRYPT_HMAC_SHA3_256_STATE *PCSYMCRYPT_HMAC_SHA3_256_STATE;15811582//1583// SYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY1584//1585// Data structure to store an expanded key for HMAC-SHA3-3841586//1587typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY1588{1589SYMCRYPT_HMAC_EXPANDED_KEY generic;15901591} SYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY;1592typedef const SYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY;15931594//1595// SYMCRYPT_HMAC_SHA3_384_STATE1596//1597// Data structure that encodes an ongoing HMAC-SHA3-384 computation.1598//1599typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_384_STATE1600{1601SYMCRYPT_HMAC_STATE generic;16021603} SYMCRYPT_HMAC_SHA3_384_STATE, *PSYMCRYPT_HMAC_SHA3_384_STATE;1604typedef const SYMCRYPT_HMAC_SHA3_384_STATE *PCSYMCRYPT_HMAC_SHA3_384_STATE;16051606//1607// SYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY1608//1609// Data structure to store an expanded key for HMAC-SHA3-5121610//1611typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY1612{1613SYMCRYPT_HMAC_EXPANDED_KEY generic;16141615} SYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY, *PSYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY;1616typedef const SYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY * PCSYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY;16171618//1619// SYMCRYPT_HMAC_SHA3_512_STATE1620//1621// Data structure that encodes an ongoing HMAC-SHA3-512 computation.1622//1623typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_HMAC_SHA3_512_STATE1624{1625SYMCRYPT_HMAC_STATE generic;16261627} SYMCRYPT_HMAC_SHA3_512_STATE, *PSYMCRYPT_HMAC_SHA3_512_STATE;1628typedef const SYMCRYPT_HMAC_SHA3_512_STATE *PCSYMCRYPT_HMAC_SHA3_512_STATE;16291630//1631// SYMCRYPT_AES_EXPANDED_KEY1632//1633// Expanded key for AES operations.1634//1635typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_AES_EXPANDED_KEY {1636SYMCRYPT_ALIGN BYTE RoundKey[29][4][4];1637// Round keys, first the encryption round keys in encryption order,1638// followed by the decryption round keys in decryption order.1639// The first decryption round key is the last encryption round key.1640// AES-256 has 14 rounds and thus 15 round keys for encryption and 151641// for decryption. As they share one round key, we need room for 29.1642BYTE (*lastEncRoundKey)[4][4]; // Pointer to last encryption round key1643// also the first round key for decryption1644BYTE (*lastDecRoundKey)[4][4]; // Pointer to last decryption round key.16451646SYMCRYPT_MAGIC_FIELD1647} SYMCRYPT_AES_EXPANDED_KEY, *PSYMCRYPT_AES_EXPANDED_KEY;1648typedef const SYMCRYPT_AES_EXPANDED_KEY * PCSYMCRYPT_AES_EXPANDED_KEY;16491650//1651// AES-CMAC1652//1653// Note: SYMCRYPT_AES_BLOCK_SIZE is not yet defined, so we use1654// literal constants instead.1655//1656typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_AES_CMAC_EXPANDED_KEY1657{1658SYMCRYPT_AES_EXPANDED_KEY aesKey;1659BYTE K1[16];1660BYTE K2[16];1661SYMCRYPT_MAGIC_FIELD1662} SYMCRYPT_AES_CMAC_EXPANDED_KEY, *PSYMCRYPT_AES_CMAC_EXPANDED_KEY;1663typedef const SYMCRYPT_AES_CMAC_EXPANDED_KEY * PCSYMCRYPT_AES_CMAC_EXPANDED_KEY;16641665typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_AES_CMAC_STATE1666{1667BYTE chain[16];1668BYTE buf[16];1669SIZE_T bytesInBuf;1670PCSYMCRYPT_AES_CMAC_EXPANDED_KEY pKey;16711672SYMCRYPT_MAGIC_FIELD1673} SYMCRYPT_AES_CMAC_STATE, *PSYMCRYPT_AES_CMAC_STATE;1674typedef const SYMCRYPT_AES_CMAC_STATE * PCSYMCRYPT_AES_CMAC_STATE;16751676//1677// POLY13051678//16791680typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_POLY1305_STATE1681{1682UINT32 r[4]; // R := \sum 2^{32*i} r[i]. R is already clamped.1683UINT32 s[4]; // S := \sum 2^{32*i} s[i]1684UINT32 a[5]; // Accumulator := sum 2^{32*i} a[i], a[4] <= approx 81685SIZE_T bytesInBuffer;1686BYTE buf[16]; // Partial block buffer16871688SYMCRYPT_MAGIC_FIELD1689} SYMCRYPT_POLY1305_STATE, *PSYMCRYPT_POLY1305_STATE;16901691//1692// XTS-AES1693//16941695typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_XTS_AES_EXPANDED_KEY1696{1697SYMCRYPT_AES_EXPANDED_KEY key1;1698SYMCRYPT_AES_EXPANDED_KEY key2;1699} SYMCRYPT_XTS_AES_EXPANDED_KEY, *PSYMCRYPT_XTS_AES_EXPANDED_KEY;1700typedef const SYMCRYPT_XTS_AES_EXPANDED_KEY * PCSYMCRYPT_XTS_AES_EXPANDED_KEY;170117021703//-----------------------------------------------------------------1704// Mac description table1705// Below are the typedefs for the Mac description table type1706// Callers can use this to define Mac algorithm they want to use1707//17081709#define SYMCRYPT_MAC_MAX_RESULT_SIZE SYMCRYPT_HMAC_SHA512_RESULT_SIZE17101711typedef union _SYMCRYPT_MAC_STATE1712{1713SYMCRYPT_HMAC_MD5_STATE md5State;1714SYMCRYPT_HMAC_SHA1_STATE sha1State;1715SYMCRYPT_HMAC_SHA224_STATE sha224State;1716SYMCRYPT_HMAC_SHA256_STATE sha256State;1717SYMCRYPT_HMAC_SHA384_STATE sha384State;1718SYMCRYPT_HMAC_SHA512_STATE sha512State;1719SYMCRYPT_HMAC_SHA512_224_STATE sha512_224State;1720SYMCRYPT_HMAC_SHA512_256_STATE sha512_256State;1721SYMCRYPT_HMAC_SHA3_224_STATE sha3_224State;1722SYMCRYPT_HMAC_SHA3_256_STATE sha3_256State;1723SYMCRYPT_HMAC_SHA3_384_STATE sha3_384State;1724SYMCRYPT_HMAC_SHA3_512_STATE sha3_512State;1725SYMCRYPT_AES_CMAC_STATE aescmacState;1726SYMCRYPT_KMAC128_STATE kmac128State;1727SYMCRYPT_KMAC256_STATE kmac256State;1728} SYMCRYPT_MAC_STATE, *PSYMCRYPT_MAC_STATE;1729typedef const SYMCRYPT_MAC_STATE *PCSYMCRYPT_MAC_STATE;17301731typedef union _SYMCRYPT_MAC_EXPANDED_KEY1732{1733SYMCRYPT_HMAC_MD5_EXPANDED_KEY md5Key;1734SYMCRYPT_HMAC_SHA1_EXPANDED_KEY sha1Key;1735SYMCRYPT_HMAC_SHA224_EXPANDED_KEY sha224Key;1736SYMCRYPT_HMAC_SHA256_EXPANDED_KEY sha256Key;1737SYMCRYPT_HMAC_SHA384_EXPANDED_KEY sha384Key;1738SYMCRYPT_HMAC_SHA512_EXPANDED_KEY sha512Key;1739SYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY sha512_224Key;1740SYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY sha512_256Key;1741SYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY sha3_224Key;1742SYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY sha3_256Key;1743SYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY sha3_384Key;1744SYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY sha3_512Key;1745SYMCRYPT_AES_CMAC_EXPANDED_KEY aescmacKey;1746SYMCRYPT_KMAC128_EXPANDED_KEY kmac128Key;1747SYMCRYPT_KMAC256_EXPANDED_KEY kmac256Key;1748} SYMCRYPT_MAC_EXPANDED_KEY, *PSYMCRYPT_MAC_EXPANDED_KEY;1749typedef const SYMCRYPT_MAC_EXPANDED_KEY *PCSYMCRYPT_MAC_EXPANDED_KEY;17501751typedef SYMCRYPT_ERROR (SYMCRYPT_CALL * PSYMCRYPT_MAC_EXPAND_KEY)1752( PVOID pExpandedKey, PCBYTE pbKey, SIZE_T cbKey );1753typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_INIT) ( PVOID pState, PCVOID pExpandedKey );1754typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_APPEND)( PVOID pState, PCBYTE pbData, SIZE_T cbData );1755typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_RESULT) ( PVOID pState, PVOID pbResult );1756typedef VOID (SYMCRYPT_CALL * PSYMCRYPT_MAC_RESULT_EX) ( PVOID pState, PVOID pbResult, SIZE_T cbResult );17571758typedef struct _SYMCRYPT_MAC1759{1760PSYMCRYPT_MAC_EXPAND_KEY expandKeyFunc;1761PSYMCRYPT_MAC_INIT initFunc;1762PSYMCRYPT_MAC_APPEND appendFunc;1763PSYMCRYPT_MAC_RESULT resultFunc;1764SIZE_T expandedKeySize;1765SIZE_T stateSize;1766SIZE_T resultSize;1767const PCSYMCRYPT_HASH * ppHashAlgorithm; // NULL for MACs not based on hashes1768UINT32 outerChainingStateOffset; // Offset into expanded key of outer chaining state; 0 for non-HMAC algorithms1769} SYMCRYPT_MAC, *PSYMCRYPT_MAC;1770typedef const SYMCRYPT_MAC *PCSYMCRYPT_MAC;1771177217731774//1775// 3DES1776//1777typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_3DES_EXPANDED_KEY {1778UINT32 roundKey[3][16][2]; // 3 keys, 16 rounds, 2 UINT32s/round1779SYMCRYPT_MAGIC_FIELD1780} SYMCRYPT_3DES_EXPANDED_KEY, *PSYMCRYPT_3DES_EXPANDED_KEY;1781typedef const SYMCRYPT_3DES_EXPANDED_KEY * PCSYMCRYPT_3DES_EXPANDED_KEY;17821783//1784// DES1785//1786typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_DES_EXPANDED_KEY {1787SYMCRYPT_3DES_EXPANDED_KEY threeDes;1788} SYMCRYPT_DES_EXPANDED_KEY, *PSYMCRYPT_DES_EXPANDED_KEY;1789typedef const SYMCRYPT_DES_EXPANDED_KEY * PCSYMCRYPT_DES_EXPANDED_KEY;17901791//1792// DESX1793//1794typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_DESX_EXPANDED_KEY {1795SYMCRYPT_DES_EXPANDED_KEY desKey;1796BYTE inputWhitening[8];1797BYTE outputWhitening[8];1798} SYMCRYPT_DESX_EXPANDED_KEY, *PSYMCRYPT_DESX_EXPANDED_KEY;1799typedef const SYMCRYPT_DESX_EXPANDED_KEY * PCSYMCRYPT_DESX_EXPANDED_KEY;18001801//1802// RC21803//1804typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_RC2_EXPANDED_KEY {1805UINT16 K[64];1806SYMCRYPT_MAGIC_FIELD1807} SYMCRYPT_RC2_EXPANDED_KEY, *PSYMCRYPT_RC2_EXPANDED_KEY;1808typedef const SYMCRYPT_RC2_EXPANDED_KEY * PCSYMCRYPT_RC2_EXPANDED_KEY;180918101811//1812// CCM states for incremental computations1813//1814#define SYMCRYPT_CCM_BLOCK_SIZE (16)18151816typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_CCM_STATE {1817PCSYMCRYPT_BLOCKCIPHER pBlockCipher;1818PCVOID pExpandedKey;1819UINT64 cbData; // exact length of data1820SIZE_T cbTag;1821SIZE_T cbNonce;1822SIZE_T cbCounter; // # bytes in counter field1823UINT64 bytesProcessed; // data bytes processed so far1824_Field_range_( 0, SYMCRYPT_CCM_BLOCK_SIZE-1 ) SIZE_T bytesInMacBlock;1825SYMCRYPT_ALIGN BYTE counterBlock[SYMCRYPT_CCM_BLOCK_SIZE]; // Current counter block value1826SYMCRYPT_ALIGN BYTE macBlock[SYMCRYPT_CCM_BLOCK_SIZE]; // Current state of the CBC-MAC part of CCM1827SYMCRYPT_ALIGN BYTE keystreamBlock[SYMCRYPT_CCM_BLOCK_SIZE]; // Remaining key stream if partial block has been processed1828SYMCRYPT_MAGIC_FIELD1829} SYMCRYPT_CCM_STATE, *PSYMCRYPT_CCM_STATE;183018311832//1833// GHash & GCM1834//18351836typedef union _SYMCRYPT_GCM_SUPPORTED_BLOCKCIPHER_KEYS1837{1838SYMCRYPT_AES_EXPANDED_KEY aes;1839} SYMCRYPT_GCM_SUPPORTED_BLOCKCIPHER_KEYS;18401841#define SYMCRYPT_GCM_BLOCKCIPHER_KEY_SIZE sizeof( union _SYMCRYPT_GCM_SUPPORTED_BLOCKCIPHER_KEYS )18421843#define SYMCRYPT_GF128_FIELD_SIZE (128)1844#define SYMCRYPT_GF128_BLOCK_SIZE (16) // # bytes in a field element/block1845#define SYMCRYPT_GCM_BLOCK_SIZE (16)1846#define SYMCRYPT_GCM_MAX_KEY_SIZE (32)184718481849#define SYMCRYPT_GCM_MAX_DATA_SIZE (((UINT64)1 << 36) - 32)18501851#define SYMCRYPT_GCM_BLOCK_MOD_MASK (SYMCRYPT_GCM_BLOCK_SIZE - 1)1852#define SYMCRYPT_GCM_BLOCK_ROUND_MASK (~SYMCRYPT_GCM_BLOCK_MOD_MASK)18531854#if SYMCRYPT_CPU_X861855//1856// x86 needs extra alignment of the GHASH expanded key to support1857// aligned (fast) XMM access. AMD64 has enough natural alignment to1858// achieve this.1859//1860#define SYMCRYPT_GHASH_EXTRA_KEY_ALIGNMENT1861#endif18621863#define SYMCRYPT_GHASH_ALLOW_XMM (SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64)1864#define SYMCRYPT_GHASH_ALLOW_NEON (SYMCRYPT_CPU_ARM | SYMCRYPT_CPU_ARM64)186518661867#if SYMCRYPT_CPU_ARM1868#include <arm_neon.h>1869#if SYMCRYPT_GNUC || defined(__clang__)1870#define __n128 uint32x4_t1871#define __n64 uint64x1_t1872#endif18731874#elif SYMCRYPT_CPU_ARM6418751876#if SYMCRYPT_MS_VC && !defined(__clang__)1877#include <arm64_neon.h>18781879// See section 6.7.8 of the C standard for details on this initializer usage.1880#define SYMCRYPT_SET_N128_U64(d0, d1) \1881((__n128) {.n128_u64 = {d0, d1}})1882#define SYMCRYPT_SET_N64_U64(d0) \1883((__n64) {.n64_u64 = {d0}})1884#define SYMCRYPT_SET_N128_U8(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15) \1885((__n128) {.n128_u8 = {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15}})1886#else1887#include <arm_neon.h>18881889#define __n128 uint8x16_t1890#define __n64 uint8x8_t18911892#define SYMCRYPT_SET_N128_U64(d0, d1) \1893((__n128) ((uint64x2_t) {d0, d1}))1894#define SYMCRYPT_SET_N64_U64(d0) \1895((__n64) ((uint64x1_t) {d0}))1896#define SYMCRYPT_SET_N128_U8(b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15) \1897((__n128) ((uint8x16_t) {b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15}))18981899#define vmullq_p64( a, b ) ((__n128) vmull_p64(vgetq_lane_p64((poly64x2_t)a, 0), vgetq_lane_p64((poly64x2_t)b, 0)))1900#define vmull_p64( a, b ) ((__n128) vmull_p64( (poly64_t)a, (poly64_t)b ))1901#define vmull_high_p64( a, b ) ((__n128) vmull_high_p64( (poly64x2_t)a, (poly64x2_t)b ))1902#endif19031904#endif19051906//1907// All platforms use the same in-memory representation:1908// elements of GF(2^128) stored as two 64-bit integers which are best1909// interpreted as a single 128-bit integer, least significant half first.1910// Note: the actual GF(2^128) bit order is reversed in the standard1911// for some reason; the1912// polynomial \sum b_i x^i is represented by integer \sum b_i 2^{127-i})1913// On x86/amd64 the same in-memory byte structure is also accessed as an1914// __m128i, which works as both the UINT64s, UINT32s, and the __m128i use1915// LSBfirst convention.1916//1917typedef SYMCRYPT_ALIGN_UNION _SYMCRYPT_GF128_ELEMENT {1918UINT64 ull[2];1919#if SYMCRYPT_GHASH_ALLOW_XMM1920//1921// The XMM code accesses this both as UINT32[] and __m128i1922// This is safe as XMM code only runs on little endian machines so the1923// ordering is known.1924//1925__m128i m128i;1926UINT32 ul[4];1927#endif1928#if SYMCRYPT_GHASH_ALLOW_NEON1929__n128 n128;1930UINT32 ul[4];1931#endif1932} SYMCRYPT_GF128_ELEMENT, *PSYMCRYPT_GF128_ELEMENT;1933typedef const SYMCRYPT_GF128_ELEMENT * PCSYMCRYPT_GF128_ELEMENT;1934193519361937typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_GHASH_EXPANDED_KEY {1938#if defined( SYMCRYPT_GHASH_EXTRA_KEY_ALIGNMENT )1939UINT32 tableOffset;1940BYTE tableSpace[ (SYMCRYPT_GF128_FIELD_SIZE + 1) * sizeof( SYMCRYPT_GF128_ELEMENT ) ];1941#else1942SYMCRYPT_GF128_ELEMENT table[ SYMCRYPT_GF128_FIELD_SIZE ];1943#endif1944} SYMCRYPT_GHASH_EXPANDED_KEY, *PSYMCRYPT_GHASH_EXPANDED_KEY;1945typedef const SYMCRYPT_GHASH_EXPANDED_KEY * PCSYMCRYPT_GHASH_EXPANDED_KEY;194619471948typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_GCM_EXPANDED_KEY {1949SYMCRYPT_GHASH_EXPANDED_KEY ghashKey;1950PCSYMCRYPT_BLOCKCIPHER pBlockCipher;1951SYMCRYPT_GCM_SUPPORTED_BLOCKCIPHER_KEYS blockcipherKey;1952SIZE_T cbKey;1953BYTE abKey[SYMCRYPT_GCM_MAX_KEY_SIZE];1954SYMCRYPT_MAGIC_FIELD1955} SYMCRYPT_GCM_EXPANDED_KEY, * PSYMCRYPT_GCM_EXPANDED_KEY;1956typedef const SYMCRYPT_GCM_EXPANDED_KEY * PCSYMCRYPT_GCM_EXPANDED_KEY;195719581959typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_GCM_STATE {1960PCSYMCRYPT_GCM_EXPANDED_KEY pKey;1961UINT64 cbData; // Number of data bytes1962UINT64 cbAuthData; // Number of AAD bytes1963_Field_range_( 0, SYMCRYPT_GCM_BLOCK_SIZE-1 ) SIZE_T bytesInMacBlock;1964SYMCRYPT_GF128_ELEMENT ghashState;1965SYMCRYPT_ALIGN BYTE counterBlock[SYMCRYPT_GCM_BLOCK_SIZE];1966SYMCRYPT_ALIGN BYTE macBlock[SYMCRYPT_GCM_BLOCK_SIZE];1967SYMCRYPT_ALIGN BYTE keystreamBlock[SYMCRYPT_GCM_BLOCK_SIZE];1968SYMCRYPT_MAGIC_FIELD1969} SYMCRYPT_GCM_STATE, * PSYMCRYPT_GCM_STATE;1970typedef const SYMCRYPT_GCM_STATE * PCSYMCRYPT_GCM_STATE;197119721973//1974// Block ciphers1975//1976#define SYMCRYPT_MAX_BLOCK_SIZE (32) // max block length of a block cipher.19771978typedef SYMCRYPT_ERROR( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_EXPAND_KEY )1979(PVOID pExpandedKey, PCBYTE pbKey, SIZE_T cbKey);1980typedef VOID( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_CRYPT ) (PCVOID pExpandedKey, PCBYTE pbSrc, PBYTE pbDst);1981typedef VOID( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_CRYPT_ECB ) (PCVOID pExpandedKey, PCBYTE pbSrc, PBYTE pbDst, SIZE_T cbData);1982typedef VOID( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE ) (PCVOID pExpandedKey, PBYTE pbChainingValue, PCBYTE pbSrc, PBYTE pbDst, SIZE_T cbData);1983typedef VOID( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_MAC_MODE ) (PCVOID pExpandedKey, PBYTE pbChainingValue, PCBYTE pbSrc, SIZE_T cbData);1984typedef VOID( SYMCRYPT_CALL * PSYMCRYPT_BLOCKCIPHER_AEADPART_MODE ) (PVOID pState, PCBYTE pbSrc, PBYTE pbDst, SIZE_T cbData);19851986struct _SYMCRYPT_BLOCKCIPHER {1987PSYMCRYPT_BLOCKCIPHER_EXPAND_KEY expandKeyFunc; // mandatory1988PSYMCRYPT_BLOCKCIPHER_CRYPT encryptFunc; // mandatory1989PSYMCRYPT_BLOCKCIPHER_CRYPT decryptFunc; // mandatory1990PSYMCRYPT_BLOCKCIPHER_CRYPT_ECB ecbEncryptFunc; // NULL if no optimized version available1991PSYMCRYPT_BLOCKCIPHER_CRYPT_ECB ecbDecryptFunc; // NULL if no optimized version available1992PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE cbcEncryptFunc; // NULL if no optimized version available1993PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE cbcDecryptFunc; // NULL if no optimized version available1994PSYMCRYPT_BLOCKCIPHER_MAC_MODE cbcMacFunc; // NULL if no optimized version available1995PSYMCRYPT_BLOCKCIPHER_CRYPT_MODE ctrMsb64Func; // NULL if no optimized version available1996PSYMCRYPT_BLOCKCIPHER_AEADPART_MODE gcmEncryptPartFunc; // NULL if no optimized version available1997PSYMCRYPT_BLOCKCIPHER_AEADPART_MODE gcmDecryptPartFunc; // NULL if no optimized version available1998_Field_range_( 1, SYMCRYPT_MAX_BLOCK_SIZE ) SIZE_T blockSize; // = SYMCRYPT_XXX_BLOCK_SIZE, power of 2, 1 <= value <= 32.1999SIZE_T expandedKeySize; // = sizeof( SYMCRYPT_XXX_EXPANDED_KEY )2000};2001200220032004//2005// Session structs2006//20072008#define SYMCRYPT_FLAG_SESSION_ENCRYPT (0x1)20092010//2011// SYMCRYPT_SESSION tracks the Nonces being used in a session. It is used differently depending on2012// whether the session is an Encryption session or a Decryption session.2013//2014// In Encryption sessions, SYMCRYPT_SESSION tracks the Nonce which was used in the most recent2015// attempted encryption in the session.2016// messageNumber is atomically incremented by each encryption call, and the encryption method uses2017// the messageNumber value that is the _result_ of the increment.2018//2019// In Decryption sessions, SYMCRYPT_SESSION tracks the most recently received Nonces in a series of2020// successful decryptions. Nonces used in unsuccessful decryption calls do not update SYMCRYPT_SESSION.2021// Information is tracked such that the decryption function can detect repeated Nonce values and2022// fail decryption in this case. In order for this to work the message numbers that are provided2023// to decrypt calls must be somewhat ordered. Provided message numbers may be arbitrarily far ahead2024// of previously successfully decrypted message numbers, but may only be up to 63 behind the highest2025// message number successfully decrypted so far.2026// messageNumber normally represents the highest message number used in a successful decryption in2027// this session. (The exception is at initialization, where messageNumber is initialized to 642028// without the corresponding 0th bit in the replayMask being set - this initial state represents2029// there have been no successful decryptions yet, and that the earliest messageNumber that can be2030// successfully received is 1)2031// replayMask represents whether a window of 64 message numbers up to messageNumber have already been2032// successfully used;2033// bit n of replayMask (from n=0 to n=63) represents message number = (messageNumber-n), 0 means not2034// yet used, and 1 means already used in a successful decryption call2035//20362037#if SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM642038#define SYMCRYPT_USE_CAS128 (1)20392040// For CompareAndSwap128 method, SYMCRYPT_SESSION must be aligned to 16B2041#define SYMCRYPT_ALIGN_SESSION SYMCRYPT_ALIGN_TYPE_AT(struct, 16)2042#else2043#define SYMCRYPT_USE_CAS128 (0)20442045// For method with only 64-bit atomics, SYMCRYPT_SESSION must be aligned to 8B2046#define SYMCRYPT_ALIGN_SESSION SYMCRYPT_ALIGN_TYPE_AT(struct, 8)2047#endif20482049// Nested struct used within SYMCRYPT_SESSION2050typedef SYMCRYPT_ALIGN_SESSION _SYMCRYPT_SESSION_REPLAY_STATE {2051UINT64 replayMask;2052// 64 bit mask representing message numbers previously successfully decrypted up to 632053// before the most recent message number.20542055UINT64 messageNumber;2056// the last 8 bytes of the Nonce (MSB-first)2057} SYMCRYPT_SESSION_REPLAY_STATE, * PSYMCRYPT_SESSION_REPLAY_STATE;2058typedef const SYMCRYPT_SESSION_REPLAY_STATE * PCSYMCRYPT_SESSION_REPLAY_STATE;20592060typedef SYMCRYPT_ALIGN_SESSION _SYMCRYPT_SESSION {2061SYMCRYPT_SESSION_REPLAY_STATE replayState;2062// nested replayState struct is to improve code clarity in SymCryptSessionDecryptUpdate*20632064UINT32 senderId;2065// the first 4 bytes of the Nonce (MSB-first)2066// (set by the caller and constant for the lifetime of a session)20672068UINT32 flags;2069// SYMCRYPT_FLAG_SESSION_ENCRYPT indicates the struct is to be used for an encryption session,2070// otherwise the struct is to be used for a decryption session20712072PVOID pMutex;2073// Pointer to a fast single-process mutex object used to enable atomic update of replayMask and2074// messageNumber in the absence of support for a 128b CAS operation2075} SYMCRYPT_SESSION, * PSYMCRYPT_SESSION;20762077#define SYMCRYPT_SESSION_MAX_MESSAGE_NUMBER (0xffffffff00000000ull)2078// We do not allow messageNumber to go above some maximum value (currently 2^64 - 2^32)2079// This gives us a large window to prevent many concurrent encryption threads from updating the2080// session such that the messageNumber overflows and the same IV is used in many encryptions2081// (i.e. we would only potentially get a spurious success using a repeated IV when there are2082// >2^32 concurrent threads!)20832084#if SYMCRYPT_USE_CAS1282085C_ASSERT(SYMCRYPT_FIELD_OFFSET(SYMCRYPT_SESSION, replayState.replayMask) == 0);2086C_ASSERT(SYMCRYPT_FIELD_OFFSET(SYMCRYPT_SESSION, replayState.messageNumber) == 8);2087// For CompareAndSwap128 method, replayMask and messageNumber must be tightly packed2088#endif20892090//2091// RC42092//20932094//2095// Some CPUs like the S array type to be larger than BYTE. We abstract the data type2096// of the S array to accommodate such CPUs in future.2097//20982099typedef BYTE SYMCRYPT_RC4_S_TYPE;21002101typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_RC4_STATE {2102SYMCRYPT_RC4_S_TYPE S[256];2103BYTE i;2104BYTE j;2105SYMCRYPT_MAGIC_FIELD2106} SYMCRYPT_RC4_STATE, *PSYMCRYPT_RC4_STATE;21072108//2109// ChaCha202110//21112112typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_CHACHA20_STATE {2113UINT32 key[8];2114UINT32 nonce[3];2115UINT64 offset; // offset to use for next operation2116BOOLEAN keystreamBufferValid; // keystream buffer matches offset value2117BYTE keystream[64];2118} SYMCRYPT_CHACHA20_STATE, *PSYMCRYPT_CHACHA20_STATE;211921202121//2122// AES_CTR_DRBG2123//21242125typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_RNG_AES_STATE {2126//2127// Key and V value are in one array, to allow fast generation of both of them2128// in a single call.2129//2130BYTE keyAndV[32 + 16];2131BYTE previousBlock[16];2132UINT64 requestCounter; // called reseed_counter in SP 800-902133BOOLEAN fips140_2Check; // set if the FIPS 140-2 continuous self-test is required2134SYMCRYPT_MAGIC_FIELD2135} SYMCRYPT_RNG_AES_STATE, * PSYMCRYPT_RNG_AES_STATE;21362137typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_RNG_AES_FIPS140_2_STATE {2138SYMCRYPT_RNG_AES_STATE rng;2139} SYMCRYPT_RNG_AES_FIPS140_2_STATE, *PSYMCRYPT_RNG_AES_FIPS140_2_STATE;214021412142//2143// MARVIN322144//21452146typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MARVIN32_EXPANDED_SEED2147{2148UINT32 s[2];2149SYMCRYPT_MAGIC_FIELD2150} SYMCRYPT_MARVIN32_EXPANDED_SEED, *PSYMCRYPT_MARVIN32_EXPANDED_SEED;2151typedef const SYMCRYPT_MARVIN32_EXPANDED_SEED * PCSYMCRYPT_MARVIN32_EXPANDED_SEED;215221532154typedef SYMCRYPT_MARVIN32_EXPANDED_SEED SYMCRYPT_MARVIN32_CHAINING_STATE, * PSYMCRYPT_MARVIN32_CHAINING_STATE;21552156typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_MARVIN32_STATE2157{2158SYMCRYPT_ALIGN BYTE buffer[8]; // 4 bytes of data, 4 more bytes for final padding2159SYMCRYPT_MARVIN32_CHAINING_STATE chain; // chaining state2160PCSYMCRYPT_MARVIN32_EXPANDED_SEED pSeed; //2161UINT32 dataLength; // length of the data processed so far, mod 2^322162SYMCRYPT_MAGIC_FIELD2163} SYMCRYPT_MARVIN32_STATE, *PSYMCRYPT_MARVIN32_STATE;2164typedef const SYMCRYPT_MARVIN32_STATE *PCSYMCRYPT_MARVIN32_STATE;216521662167//2168// Export blob sizes2169//21702171#define SYMCRYPT_MD2_STATE_EXPORT_SIZE (80)2172#define SYMCRYPT_MD4_STATE_EXPORT_SIZE (116)2173#define SYMCRYPT_MD5_STATE_EXPORT_SIZE (116)2174#define SYMCRYPT_SHA1_STATE_EXPORT_SIZE (120)2175#define SYMCRYPT_SHA224_STATE_EXPORT_SIZE (132)2176#define SYMCRYPT_SHA256_STATE_EXPORT_SIZE (132)2177#define SYMCRYPT_SHA384_STATE_EXPORT_SIZE (236)2178#define SYMCRYPT_SHA512_STATE_EXPORT_SIZE (236)2179#define SYMCRYPT_SHA512_224_STATE_EXPORT_SIZE (236)2180#define SYMCRYPT_SHA512_256_STATE_EXPORT_SIZE (236)21812182#define SYMCRYPT_KECCAK_STATE_EXPORT_SIZE (234)2183#define SYMCRYPT_SHA3_224_STATE_EXPORT_SIZE SYMCRYPT_KECCAK_STATE_EXPORT_SIZE2184#define SYMCRYPT_SHA3_256_STATE_EXPORT_SIZE SYMCRYPT_KECCAK_STATE_EXPORT_SIZE2185#define SYMCRYPT_SHA3_384_STATE_EXPORT_SIZE SYMCRYPT_KECCAK_STATE_EXPORT_SIZE2186#define SYMCRYPT_SHA3_512_STATE_EXPORT_SIZE SYMCRYPT_KECCAK_STATE_EXPORT_SIZE218721882189//2190// KDF algorithms2191//21922193//2194// PBKDF22195//21962197typedef struct _SYMCRYPT_PBKDF2_EXPANDED_KEY {2198SYMCRYPT_MAC_EXPANDED_KEY macKey;2199PCSYMCRYPT_MAC macAlg;2200} SYMCRYPT_PBKDF2_EXPANDED_KEY, *PSYMCRYPT_PBKDF2_EXPANDED_KEY;2201typedef const SYMCRYPT_PBKDF2_EXPANDED_KEY *PCSYMCRYPT_PBKDF2_EXPANDED_KEY;22022203//2204// SP 800-1082205//22062207typedef struct _SYMCRYPT_SP800_108_EXPANDED_KEY {2208SYMCRYPT_MAC_EXPANDED_KEY macKey;2209PCSYMCRYPT_MAC macAlg;2210} SYMCRYPT_SP800_108_EXPANDED_KEY, *PSYMCRYPT_SP800_108_EXPANDED_KEY;2211typedef const SYMCRYPT_SP800_108_EXPANDED_KEY *PCSYMCRYPT_SP800_108_EXPANDED_KEY;22122213//2214// TLS PRF 1.12215//22162217typedef struct _SYMCRYPT_TLSPRF1_1_EXPANDED_KEY {2218SYMCRYPT_HMAC_MD5_EXPANDED_KEY macMd5Key;2219SYMCRYPT_HMAC_SHA1_EXPANDED_KEY macSha1Key;2220} SYMCRYPT_TLSPRF1_1_EXPANDED_KEY, *PSYMCRYPT_TLSPRF1_1_EXPANDED_KEY;2221typedef const SYMCRYPT_TLSPRF1_1_EXPANDED_KEY *PCSYMCRYPT_TLSPRF1_1_EXPANDED_KEY;22222223//2224// TLS PRF 1.22225//22262227typedef struct _SYMCRYPT_TLSPRF1_2_EXPANDED_KEY {2228SYMCRYPT_MAC_EXPANDED_KEY macKey;2229PCSYMCRYPT_MAC macAlg;2230} SYMCRYPT_TLSPRF1_2_EXPANDED_KEY, *PSYMCRYPT_TLSPRF1_2_EXPANDED_KEY;2231typedef const SYMCRYPT_TLSPRF1_2_EXPANDED_KEY *PCSYMCRYPT_TLSPRF1_2_EXPANDED_KEY;22322233//2234// SSH-KDF2235//2236typedef struct _SYMCRYPT_SSHKDF_EXPANDED_KEY {2237PCSYMCRYPT_HASH pHashFunc;2238SYMCRYPT_HASH_STATE hashState;2239} SYMCRYPT_SSHKDF_EXPANDED_KEY, *PSYMCRYPT_SSHKDF_EXPANDED_KEY;2240typedef const SYMCRYPT_SSHKDF_EXPANDED_KEY *PCSYMCRYPT_SSHKDF_EXPANDED_KEY;22412242//2243// SRTP-KDF2244//2245typedef struct _SYMCRYPT_SRTPKDF_EXPANDED_KEY {2246SYMCRYPT_AES_EXPANDED_KEY aesExpandedKey;2247} SYMCRYPT_SRTPKDF_EXPANDED_KEY, *PSYMCRYPT_SRTPKDF_EXPANDED_KEY;2248typedef const SYMCRYPT_SRTPKDF_EXPANDED_KEY *PCSYMCRYPT_SRTPKDF_EXPANDED_KEY;22492250//2251// HKDF2252//22532254typedef struct _SYMCRYPT_HKDF_EXPANDED_KEY {2255SYMCRYPT_MAC_EXPANDED_KEY macKey;2256PCSYMCRYPT_MAC macAlg;2257} SYMCRYPT_HKDF_EXPANDED_KEY, *PSYMCRYPT_HKDF_EXPANDED_KEY;2258typedef const SYMCRYPT_HKDF_EXPANDED_KEY *PCSYMCRYPT_HKDF_EXPANDED_KEY;22592260//2261// SSKDF2262//2263typedef struct _SYMCRYPT_SSKDF_MAC_EXPANDED_SALT {2264SYMCRYPT_MAC_EXPANDED_KEY macKey;2265PCSYMCRYPT_MAC macAlg;2266} SYMCRYPT_SSKDF_MAC_EXPANDED_SALT, *PSYMCRYPT_SSKDF_MAC_EXPANDED_SALT;2267typedef const SYMCRYPT_SSKDF_MAC_EXPANDED_SALT *PCSYMCRYPT_SSKDF_MAC_EXPANDED_SALT;22682269//2270// Digit & alignment sizes.2271//2272// WARNING: do not change these without updating all the optimized code,2273// including assembler code.2274// The FDEF_DIGIT_SIZE is the digit size used by the FDEF format.2275//2276#if SYMCRYPT_CPU_AMD6422772278#define SYMCRYPT_FDEF_DIGIT_SIZE 642279#define SYMCRYPT_ASYM_ALIGN_VALUE 3222802281#elif SYMCRYPT_CPU_ARM6422822283#define SYMCRYPT_FDEF_DIGIT_SIZE 322284#define SYMCRYPT_ASYM_ALIGN_VALUE 3222852286#else22872288#define SYMCRYPT_FDEF_DIGIT_SIZE 162289#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.22902291#endif22922293#define SYMCRYPT_ASYM_ALIGN_UP( _p ) ((PBYTE) ( ((SIZE_T) (_p) + SYMCRYPT_ASYM_ALIGN_VALUE - 1) & ~(SYMCRYPT_ASYM_ALIGN_VALUE - 1 ) ) )229422952296//==============================================================================================2297// Object types for low-level API2298//2299// INT integer in range 0..N for some N2300// DIVISOR an integer > 0 that can be used to divide with.2301// MODULUS a value M > 1 to use in modulo-M computations2302// MODELEMENT An element in a modulo-M ring.2303// ECPOINT A point on an elliptic curve.2304//2305// These objects are all aligned to SYMCRYPT_ASYM_ALIGN2306//2307#define SYMCRYPT_ASYM_ALIGN SYMCRYPT_ALIGN_AT(SYMCRYPT_ASYM_ALIGN_VALUE)2308#if SYMCRYPT_MS_VC2309#define SYMCRYPT_ASYM_ALIGN_STRUCT SYMCRYPT_ASYM_ALIGN struct2310#elif SYMCRYPT_GNUC2311#define SYMCRYPT_ASYM_ALIGN_STRUCT struct SYMCRYPT_ASYM_ALIGN2312#else2313#error Unknown compiler2314#endif23152316SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_INT;2317typedef struct _SYMCRYPT_INT SYMCRYPT_INT;2318typedef SYMCRYPT_INT * PSYMCRYPT_INT;2319typedef const SYMCRYPT_INT * PCSYMCRYPT_INT;23202321SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_DIVISOR;2322typedef struct _SYMCRYPT_DIVISOR SYMCRYPT_DIVISOR;2323typedef SYMCRYPT_DIVISOR * PSYMCRYPT_DIVISOR;2324typedef const SYMCRYPT_DIVISOR * PCSYMCRYPT_DIVISOR;23252326SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_MODULUS;2327typedef struct _SYMCRYPT_MODULUS SYMCRYPT_MODULUS;2328typedef SYMCRYPT_MODULUS * PSYMCRYPT_MODULUS;2329typedef const SYMCRYPT_MODULUS * PCSYMCRYPT_MODULUS;23302331SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_MODELEMENT;2332typedef struct _SYMCRYPT_MODELEMENT SYMCRYPT_MODELEMENT;2333typedef SYMCRYPT_MODELEMENT * PSYMCRYPT_MODELEMENT;2334typedef const SYMCRYPT_MODELEMENT * PCSYMCRYPT_MODELEMENT;23352336SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_ECPOINT;2337typedef struct _SYMCRYPT_ECPOINT SYMCRYPT_ECPOINT;2338typedef SYMCRYPT_ECPOINT * PSYMCRYPT_ECPOINT;2339typedef const SYMCRYPT_ECPOINT * PCSYMCRYPT_ECPOINT;234023412342//2343// Arithmetic formats2344//23452346#define SYMCRYPT_ANYSIZE 1 // used to mark arrays of arbitrary size23472348#define SYMCRYPT_FDEF_DIGIT_BITS (8*SYMCRYPT_FDEF_DIGIT_SIZE)2349#define SYMCRYPT_FDEF_DIGITS_FROM_BITS( _bits ) ( \2350((_bits)/ SYMCRYPT_FDEF_DIGIT_BITS) + \2351(( ((_bits) & (SYMCRYPT_FDEF_DIGIT_BITS-1)) + (SYMCRYPT_FDEF_DIGIT_BITS - 1) )/SYMCRYPT_FDEF_DIGIT_BITS) \2352)23532354#define SYMCRYPT_BYTES_FROM_BITS(bits) ( ( (bits) + 7 ) / 8 )23552356// The maximum number of bits in any integer value that the library supports. If the2357// caller's input exceed this bound then the integer object will not be created.2358// The caller either must ensure the bound is not exceeded, or check for NULL before2359// using created SymCrypt objects.2360// The primary purpose of this limit is to avoid integer overflows in size computations.2361// Having a reasonable upper bound avoids all size overflows, even on 32-bit CPUs2362#define SYMCRYPT_INT_MAX_BITS ((UINT32)(1 << 20))23632364//2365// Upper bound for the number of digits: this MUST be enforced on runtime2366// on all Allocate, SizeOf, and Create calls which take as input a digit number.2367//2368// Using this upper bound and the SYMCRYPT_INT_MAX_BITS upper bound we can argue2369// that no integer overflow on 32-bit sizes can happen. Note that the computed upper2370// bounds are very loose and the actual values are much smaller.2371//2372#define SYMCRYPT_FDEF_UPB_DIGITS (SYMCRYPT_FDEF_DIGITS_FROM_BITS(SYMCRYPT_INT_MAX_BITS))23732374237523762377//2378// All of the following SYMCRYPT_FDEF_SIZEOF_XXX_FROM_YYY computations for the four2379// main SymCrypt objects (INT, DIVISOR, MODULUS, MODELEMENT) return a value not2380// larger than 2^19 if the inputs _nDigits and _bits are not larger than2381// SYMCRYPT_FDEF_UPB_DIGITS and SYMCRYPT_INT_MAX_BITS respectively (For MODELEMENT this bound2382// is 2^17). The latter bounds must be enforced on runtime for all calculations taking as inputs2383// number of digits or bits.2384//2385// The 2^19 upper bound is derived from:2386// - the maximum (byte) size of an "integer": 2^20 bits / 8 = 2^17 bytes2387// - "sizeof" computations add up to less than 2^18 bytes ~ 262 Kb2388// - the modulus object contains two "integers"2389//23902391//2392// Type fields contain the following:2393// lower 16 bits: offset into virtual table (if any)2394// upper 16 bits: bits 16-23: 1-character object type. Bits 24-31: 1 char implementation type2395// The upper bits allow objects to be recognized in memory, making debugging easier.2396//23972398SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_INT {2399UINT32 type;2400_Field_range_( 1, SYMCRYPT_FDEF_UPB_DIGITS ) UINT32 nDigits; // digit size depends on run-time decisions...2401UINT32 cbSize;24022403SYMCRYPT_MAGIC_FIELD2404SYMCRYPT_ASYM_ALIGN union {2405struct {2406UINT32 uint32[SYMCRYPT_ANYSIZE]; // FDEF: array UINT32[nDigits * # uint32 per digit]2407} fdef;2408} ti; // we must have a name here. 'ti' stands for 'Type-Int', it helps catch type errors when type-casting macros are used.2409};24102411#define SYMCRYPT_FDEF_INT_PUINT32( p ) (&(p)->ti.fdef.uint32[0])241224132414#define SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nDigits ) ((_nDigits) * SYMCRYPT_FDEF_DIGIT_SIZE + sizeof( SYMCRYPT_INT ) )2415#define SYMCRYPT_FDEF_SIZEOF_INT_FROM_BITS( _bits ) SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( SYMCRYPT_FDEF_DIGITS_FROM_BITS( _bits ))24162417SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_DIVISOR {2418UINT32 type;2419_Field_range_( 1, SYMCRYPT_FDEF_UPB_DIGITS ) UINT32 nDigits; // digit size depends on run-time decisions...2420UINT32 cbSize;24212422UINT32 nBits; // # bits in divisor24232424SYMCRYPT_MAGIC_FIELD2425union{2426struct {2427UINT64 W; // approximate inverse of the divisor. Some implementations will use 64 bits, others 32 bits.2428} fdef;2429} td;2430SYMCRYPT_INT Int; // Having a full Int here uses more space, but allows any Divisor to still be used as an Int.2431// This structure is directly followed by the Int extension2432};24332434#define SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_DIGITS( _nDigits ) ((_nDigits) * SYMCRYPT_FDEF_DIGIT_SIZE + sizeof( SYMCRYPT_DIVISOR ) )2435#define SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_BITS( _bits ) SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_DIGITS( SYMCRYPT_FDEF_DIGITS_FROM_BITS( _bits ))24362437SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_MODULUS {2438UINT32 type;2439_Field_range_( 1, SYMCRYPT_FDEF_UPB_DIGITS ) UINT32 nDigits; // digit size depends on run-time decisions...2440UINT32 cbSize; // Size of modulus object24412442UINT32 flags; // The flags the modulus was created with2443UINT32 cbModElement; // Size of one modElement2444UINT64 inv64; // -1/modulus mod 2^64 (always set but only to a useful value when the modulus is odd)24452446SYMCRYPT_MAGIC_FIELD2447union{2448struct {2449//UINT32 nUint32Used; // # 32-bit words used in representing numbers. modulus < 2^{32*nUint32Used}.2450// only values used are nDigits * uint32-per-digit or specific smaller values for optimized implementations2451PCUINT32 Rsqr; // R^2 mod modulus, in uint32 form, nUint32Used words. Stored after Divisor. R = 2^{32*nUint32Used}2452} montgomery;2453struct {2454UINT32 k; // modulus = 2^<bitsize of modelement> - k2455} pseudoMersenne;2456} tm; // type specific data. Every Modulus can be used as a generic modulus, so no type-specific data for generic.24572458SYMCRYPT_DIVISOR Divisor;2459// This structure is directly followed by:2460// The extensions of the Divisor object2461// and after that:2462// FDEF: Rsqr as an array of UINT32, size = nDigits * digitsize2463// FDEF: negDivisor as an array of UINT32, size = nDigits * digitsize2464};24652466#define SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_DIGITS( _nDigits ) (sizeof( SYMCRYPT_MODULUS ) + SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_DIGITS( _nDigits ) + (2 * _nDigits * SYMCRYPT_FDEF_DIGIT_SIZE) )2467#define SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_BITS( _bits ) SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_DIGITS(SYMCRYPT_FDEF_DIGITS_FROM_BITS( _bits ))24682469SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_MODELEMENT {2470// ModElements just store the information without any header. This union makes this well-defined, and allows easy access.2471union{2472UINT32 uint32[SYMCRYPT_ANYSIZE];2473} d;2474};24752476#define SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nDigits ) ((_nDigits) * SYMCRYPT_FDEF_DIGIT_SIZE)2477#define SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_BITS( _bits ) SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( SYMCRYPT_FDEF_DIGITS_FROM_BITS( _bits ) )24782479//2480// Upper bound for scratch size computations for FDEF objects depending only on digits2481//2482// The following 14 scratch size computation macros are all of the form:2483// Some SIZEOF macros + max( some other scratch macros )2484// and all depend on some number of digits. (Slight exceptions are2485// INT_TO_MODULUS and INT_PRIME_GEN but they can fit into the below2486// rationale.)2487//2488// One can see that the deepest recursion in these macros and the biggest2489// return value is for2490// INT_PRIME_GEN -> INT_MILLER_RABIN -> MODEXP ->2491// COMMON_MOD_OPERATIONS -> SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD2492//2493// Using the 2^19 (2^17) bound on the sizeof computations the biggest contribution on the above chain is for MODEXP:2494// ((1 << SYMCRYPT_FDEF_MAX_WINDOW_MODEXP) + 2) * SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nModDigits )2495// which is bounded above by2496// (2^6 + 2) * 2^17 < 2^242497//2498// By doubling on each subsequent recursive call we get the conservative2499// upper bound for all scratch size computation macros of 2^26.2500//25012502#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits ) (16 * (_nDigits)) // unused currently, but this catches errors25032504#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MUL( _nDigits ) (16 * (_nDigits)) // unused currently, but nonzero size catches errors25052506#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( _nSrcDigits, _nDivisorDigits ) ( (_nSrcDigits + 1) * SYMCRYPT_FDEF_DIGIT_SIZE )25072508#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_EXTENDED_GCD( _nDigits ) ( \25094 * SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nDigits ) + \2510SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( 2 * _nDigits ) + \25112 * SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_DIGITS( _nDigits ) + \2512SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( 2 * _nDigits, _nDigits ), \2513SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MUL( 2 * _nDigits ), \2514SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits ) )) )25152516#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits ) \2517( (2*(_nModDigits) * SYMCRYPT_FDEF_DIGIT_SIZE) + \2518SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( 2*(_nModDigits), _nModDigits )) // for mult: tmp product + divmod scratch25192520#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_CRT_GENERATION( _nDigits ) ( \25212*SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nDigits ) + \2522SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_EXTENDED_GCD( _nDigits ), \2523SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nDigits ) ))25242525#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_CRT_SOLUTION( _nDigits ) ( \2526SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nDigits ) + \2527SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nDigits ) + \2528SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( 2*_nDigits ) + \2529SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nDigits ), \2530SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MUL( 2*_nDigits ) ))25312532#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_MODULUS( _nDigits ) ( \2533SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits ),\2534(2*_nDigits+1) * SYMCRYPT_FDEF_DIGIT_SIZE + SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( 2*_nDigits + 1, nDigits )) )25352536#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODINV( _nModDigits ) ( \25374 * SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nModDigits ) + \25383 * SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nModDigits ) + \2539SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits ) )25402541#define SYMCRYPT_FDEF_MAX_WINDOW_MODEXP (6)25422543#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODEXP( _nModDigits ) ( \2544((1 << SYMCRYPT_FDEF_MAX_WINDOW_MODEXP) + 2) * SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nModDigits ) + \2545SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits ) )25462547#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_IS_POTENTIAL_PRIME( _nDigits ) (0)25482549#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MILLER_RABIN( _nDigits ) ( \2550SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_DIGITS(_nDigits) + \25513*SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS(_nDigits) + \2552SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS(_nDigits) + \2553SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_MODULUS(_nDigits), \2554SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS(_nDigits), \2555SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODEXP( _nDigits ) )) )25562557#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_IS_PRIME( _nDigits ) ( \2558SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_IS_POTENTIAL_PRIME( _nDigits ), \2559SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MILLER_RABIN( _nDigits ) ))25602561#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_PRIME_GEN( _nDigits ) ( \2562SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS * SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_DIGITS( 1 ) + \2563SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( 1 ) + \2564SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( 1 ), \2565SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( _nDigits, 1 ), \2566SYMCRYPT_MAX( SYMCRYPT_FDEF_SIZEOF_INT_FROM_DIGITS( _nDigits ), \2567SYMCRYPT_MAX( SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_IS_POTENTIAL_PRIME( _nDigits ), \2568SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MILLER_RABIN( _nDigits ) )))))25692570//2571// Upper bound for SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODMULTIEXP2572//2573// _nBase and _nBitsExp are bounded by SYMCRYPT_MODMULTIEXP_MAX_NBASES = 8 and2574// SYMCRYPT_MODMULTIEXP_MAX_NBITSEXP = 2^20. Therefore the upper bound on this computation2575// is2576// 2^21 + 2^3*(2^6+4)*2^17 + 2^3*2^20*4 < 2^272577//2578#define SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODMULTIEXP( _nModDigits, _nBases, _nBitsExp ) ( \2579SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits ) + \2580((_nBases)*(1<<SYMCRYPT_FDEF_MAX_WINDOW_MODEXP) + 4)*SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS( _nModDigits ) + \2581(((_nBases)*(_nBitsExp)*sizeof(UINT32) + SYMCRYPT_ASYM_ALIGN_VALUE - 1) & ~(SYMCRYPT_ASYM_ALIGN_VALUE - 1)) )2582// Note: We need +4 multiplied with SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_DIGITS so that SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODMULTIEXP2583// is always at least 2 modelements bigger than SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODEXP (see modexp.c)25842585//2586// Support for masked operations25872588#define SYMCRYPT_MASK32_SET ((UINT32)-1)2589#define SYMCRYPT_MASK32_NONZERO( _v ) ((UINT32)(((UINT64)0 - (_v)) >> 32))2590#define SYMCRYPT_MASK32_ZERO( _v ) (~SYMCRYPT_MASK32_NONZERO( _v ))2591#define SYMCRYPT_MASK32_EQ( _a, _b ) (~SYMCRYPT_MASK32_NONZERO( (_a) ^ (_b) ))2592#define SYMCRYPT_MASK32_LT( _a, _b ) ((UINT32)( ((UINT64)(_a) - (_b)) >> 32 ))259325942595//2596// Dispatch definitions2597// When multiple formats are supported, this is where the information of the multiple formats is combined.2598//2599// See the comments in SYMCRYPT_FDEF_SCRATCH_XXX regarding 32 bit overflow protection. All results2600// are bounded above by 2^27.2601//26022603#define SYMCRYPT_INTERNAL_SIZEOF_INT_FROM_BITS( _bitsize ) SYMCRYPT_FDEF_SIZEOF_INT_FROM_BITS( _bitsize )2604#define SYMCRYPT_INTERNAL_SIZEOF_DIVISOR_FROM_BITS( _bitsize ) SYMCRYPT_FDEF_SIZEOF_DIVISOR_FROM_BITS( _bitsize )2605#define SYMCRYPT_INTERNAL_SIZEOF_MODULUS_FROM_BITS( _bitsize ) SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_BITS( _bitsize )2606#define SYMCRYPT_INTERNAL_SIZEOF_MODELEMENT_FROM_BITS( _bitsize ) SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_BITS( _bitsize )26072608#define SYMCRYPT_INTERNAL_SIZEOF_RSAKEY_FROM_PARAMS( modBits, nPrimes, nPubExps ) SYMCRYPT_FDEF_SIZEOF_RSAKEY_FROM_PARAMS( modBits, nPrimes, nPubExps )2609// For now we don't need the pubExpBits so we drop them, but we might use them later.26102611#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_DIVISOR( _nDigits )2612#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_MUL( _nDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_MUL( _nDigits )2613#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_DIVMOD( _nSrcDigits, _nDivisorDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_DIVMOD( _nSrcDigits, _nDivisorDigits )2614#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_EXTENDED_GCD( _nDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_EXTENDED_GCD( _nDigits )2615#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_COMMON_MOD_OPERATIONS( _nModDigits )2616#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_CRT_GENERATION( _nDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_CRT_GENERATION( _nDigits )2617#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_CRT_SOLUTION( _nDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_CRT_SOLUTION( _nDigits )2618#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_TO_MODULUS( _nDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_TO_MODULUS( _nDigits )2619#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_MODINV( _nModDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODINV( _nModDigits )2620#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_MODEXP( _nModDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODEXP( _nModDigits )2621#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_IS_PRIME( _nDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_IS_PRIME( _nDigits )2622#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_INT_PRIME_GEN( _nDigits ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_INT_PRIME_GEN( _nDigits )26232624#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_MODMULTIEXP( _nModDigits, _nBases, _nBitsExp ) SYMCRYPT_FDEF_SCRATCH_BYTES_FOR_MODMULTIEXP( _nModDigits, _nBases, _nBitsExp )26252626//2627// Forward declarations for MlKemkey types2628//2629SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_MLKEMKEY;2630typedef struct _SYMCRYPT_MLKEMKEY SYMCRYPT_MLKEMKEY;2631typedef SYMCRYPT_MLKEMKEY * PSYMCRYPT_MLKEMKEY;2632typedef const SYMCRYPT_MLKEMKEY * PCSYMCRYPT_MLKEMKEY;26332634//2635// Forward declarations for MlDsakey types2636//2637struct _SYMCRYPT_MLDSAKEY;2638typedef struct _SYMCRYPT_MLDSAKEY SYMCRYPT_MLDSAKEY;2639typedef SYMCRYPT_MLDSAKEY * PSYMCRYPT_MLDSAKEY;2640typedef const SYMCRYPT_MLDSAKEY * PCSYMCRYPT_MLDSAKEY;26412642//2643// Forward declarations for CompositeMlKemkey types2644//2645SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_COMPOSITE_MLKEMKEY;2646typedef struct _SYMCRYPT_COMPOSITE_MLKEMKEY SYMCRYPT_COMPOSITE_MLKEMKEY;2647typedef SYMCRYPT_COMPOSITE_MLKEMKEY * PSYMCRYPT_COMPOSITE_MLKEMKEY;2648typedef const SYMCRYPT_COMPOSITE_MLKEMKEY * PCSYMCRYPT_COMPOSITE_MLKEMKEY;26492650//2651// RSA padding scratch definitions2652//2653// The maximum sizes of the state and the result for all hash algorithms are2654// sizeof(SYMCRYPT_HASH_STATE) and SYMCRYPT_HASH_MAX_RESULT_SIZE, both not bigger2655// 2^20. All the nBytes inputs are bounded by 2^17 (the maximum byte-size2656// of the RSA modulus).2657//2658// Thus a total upper bound on these results is 2^20.2659//2660#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_RSA_OAEP( _hashAlgorithm, _nBytesOAEP ) ( SymCryptHashStateSize( _hashAlgorithm ) + \2661SymCryptHashResultSize( _hashAlgorithm ) + \26622*(_nBytesOAEP - 1) )26632664#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_RSA_PKCS1( _nBytesPKCS1 ) ( _nBytesPKCS1 )26652666#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_RSA_PSS( _hashAlgorithm, _nBytesMessage, _nBytesPSS ) ( SymCryptHashStateSize( _hashAlgorithm ) + \2667_nBytesMessage + \26683*(_nBytesPSS) + 5 )26692670//2671// RSAKEY Type2672//26732674#define SYMCRYPT_FDEF_SIZEOF_RSAKEY_FROM_PARAMS( modBits, nPrimes, nPubExps ) \2675sizeof( SYMCRYPT_RSAKEY ) + \2676(nPrimes + 1) * SYMCRYPT_FDEF_SIZEOF_MODULUS_FROM_BITS( modBits ) + \2677nPrimes * SYMCRYPT_FDEF_SIZEOF_MODELEMENT_FROM_BITS( modBits ) + \2678(nPrimes + 1) * nPubExps * SYMCRYPT_FDEF_SIZEOF_INT_FROM_BITS( modBits )2679// 1 modulus object per prime + 1 for the RSA modulus2680// 1 modelement for every crtInverse2681// 1 int per pubexp for each privexp + 1 int per prime*pubexp for each crtprivexp26822683#define SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES (2)2684#define SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS (1)26852686#define SYMCRYPT_RSAKEY_MIN_BITSIZE_MODULUS (256) // Some of our SCS code requires at least 32 bytes...2687#define SYMCRYPT_RSAKEY_MAX_BITSIZE_MODULUS (1 << 16) // Avoid any integer overflows in size calculations26882689// RSA FIPS self-tests require at least 496 bits to avoid fatal2690// Require caller to specify NO_FIPS for up to 1024 bits as running FIPS tests on too-small keys2691// does not make it FIPS certifiable and gives the wrong impression to callers2692#define SYMCRYPT_RSAKEY_FIPS_MIN_BITSIZE_MODULUS (1024)26932694#define SYMCRYPT_RSAKEY_MIN_BITSIZE_PRIME (128)2695#define SYMCRYPT_RSAKEY_MAX_BITSIZE_PRIME (SYMCRYPT_RSAKEY_MAX_BITSIZE_MODULUS / 2)26962697// Minimum allowable bit sizes for generated and imported parameters for2698// the RSA modulus and each prime.26992700typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_RSAKEY {2701UINT32 fAlgorithmInfo; // Tracks which algorithms the key can be used in2702// Also tracks which per-key selftests have been performed on this key2703// A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_RSAKEY_*, and2704// SYMCRYPT_PCT_* values27052706UINT32 cbTotalSize; // Total size of the rsa key2707BOOLEAN hasPrivateKey; // Set to true if there is private key information set27082709UINT32 nSetBitsOfModulus; // Bits of modulus specified during creation27102711UINT32 nBitsOfModulus; // Number of bits of the value of the modulus (not the object's size)2712UINT32 nDigitsOfModulus; // Number of digits of the modulus object (always equal to SymCryptDigitsFromBits(nSetBitsOfModulus))27132714UINT32 nPubExp; // Number of public exponents27152716UINT32 nPrimes; // Number of primes, can be 0 if the object only supports public keys2717UINT32 nBitsOfPrimes[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];2718// Number of bits of the value of each prime (not the object's size)2719UINT32 nDigitsOfPrimes[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];2720// Number of digits of each prime object2721UINT32 nMaxDigitsOfPrimes; // Maximum number of digits in nDigitsOfPrimes27222723UINT64 au64PubExp[SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS];2724// SYMCRYPT_ASYM_ALIGN'ed buffers that point to memory allocated for each object2725PBYTE pbPrimes[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];2726PBYTE pbCrtInverses[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];2727PBYTE pbPrivExps[SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS];2728PBYTE pbCrtPrivExps[SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS * SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];27292730// SymCryptObjects2731PSYMCRYPT_MODULUS pmModulus; // The modulus N=p*q2732PSYMCRYPT_MODULUS pmPrimes[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];2733// Pointers to the secret primes2734PSYMCRYPT_MODELEMENT peCrtInverses[SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];2735// Pointers to the CRT inverses of the primes2736PSYMCRYPT_INT piPrivExps[SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS];2737// Pointers to the corresponding private exponents2738PSYMCRYPT_INT piCrtPrivExps[SYMCRYPT_RSAKEY_MAX_NUMOF_PUBEXPS * SYMCRYPT_RSAKEY_MAX_NUMOF_PRIMES];2739// Pointers to the private exponents modulo each prime minus 1 (for CRT)27402741SYMCRYPT_MAGIC_FIELD2742// Followed by:2743// Modulus2744// Primes2745// CrtInverses2746// PrivExps2747// CrtPrivExps2748} SYMCRYPT_RSAKEY;2749typedef SYMCRYPT_RSAKEY * PSYMCRYPT_RSAKEY;2750typedef const SYMCRYPT_RSAKEY * PCSYMCRYPT_RSAKEY;27512752//2753// The following definitions relating to trial division are not needed by normal callers2754// but are used by the test program to measure performance of components.2755//27562757typedef struct _SYMCRYPT_TRIALDIVISION_PRIME {2758UINT64 invMod2e64; // Inverse of prime modulo 2^642759UINT64 compareLimit; // floor( (2^{64}-1)/ prime )2760} SYMCRYPT_TRIALDIVISION_PRIME, *PSYMCRYPT_TRIALDIVISION_PRIME;2761typedef const SYMCRYPT_TRIALDIVISION_PRIME * PCSYMCRYPT_TRIALDIVISION_PRIME;2762//2763// This structure is used to test whether a UINT64 is a multiple of a (small) prime.2764// Let V be the input value, P the small prime, and W the inverse of P modulo 2^64.2765// If V = k*P then V * M mod 2^64 = V/P mod 2^64 = k.2766// This holds for k = 0, 1, ..., floor( (2^{64}-1)/p ).2767// If V is not a multiple of P then the result of the multiplication must be larger than that.2768//27692770typedef struct _SYMCRYPT_TRIALDIVISION_GROUP {2771UINT32 nPrimes; // # primes are in this group (use the next ones)2772UINT32 factor[9]; // factors[i] = 2^{32*(i+1)} mod Prod where Prod = product of the primes2773// It is guaranteed that Prod <= (2^{32}-1)/92774} SYMCRYPT_TRIALDIVISION_GROUP, *PSYMCRYPT_TRIALDIVISION_GROUP;2775typedef const SYMCRYPT_TRIALDIVISION_GROUP * PCSYMCRYPT_TRIALDIVISION_GROUP;277627772778typedef struct _SYMCRYPT_TRIALDIVISION_CONTEXT {2779SIZE_T nBytesAlloc;2780UINT32 maxTrialPrime;2781PSYMCRYPT_TRIALDIVISION_GROUP pGroupList; // terminated with 0 record2782PSYMCRYPT_TRIALDIVISION_PRIME pPrimeList; // terminated with 0 record2783PUINT32 pPrimes; // terminated with a 0.2784SYMCRYPT_TRIALDIVISION_PRIME Primes3_5_17[3]; // Structures for 3, 5 and 17 in that order2785} SYMCRYPT_TRIALDIVISION_CONTEXT, *PSYMCRYPT_TRIALDIVISION_CONTEXT;2786typedef const SYMCRYPT_TRIALDIVISION_CONTEXT * PCSYMCRYPT_TRIALDIVISION_CONTEXT;27872788UINT322789SymCryptTestTrialdivisionMaxSmallPrime( PCSYMCRYPT_TRIALDIVISION_CONTEXT pContext ); // Expose small prime limit to help test code27902791//2792// DLGROUP type2793//27942795#define SYMCRYPT_DLGROUP_MIN_BITSIZE_P (32)2796#define SYMCRYPT_DLGROUP_MIN_BITSIZE_Q (31) // Q must always be at least 1 bit shorter than P2797// Minimum allowable bit sizes for generated and imported parameters for both P and2798// Q primes.27992800typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_DLGROUP {2801UINT32 cbTotalSize; // Total size of the dl group object2802BOOLEAN fHasPrimeQ; // Flag that specifies whether the object has a Q parameter28032804UINT32 nBitsOfP; // Number of bits of the value of P (not the object's size)2805UINT32 cbPrimeP; // Number of bytes of the value of P (not the object's size), equal to ceil(nBitsOfP/8)2806UINT32 nDigitsOfP; // Number of digits of the object of prime P2807UINT32 nMaxBitsOfP; // Maximum number of bits of the value of P28082809UINT32 nBitsOfQ; // Number of bits of the value of Q (not the object's bits)2810UINT32 cbPrimeQ; // Number of bytes of the value of Q (not the object's size), equal to ceil(nBitsOfQ/8)2811UINT32 nDigitsOfQ; // Number of digits of the object of prime Q2812UINT32 nMaxBitsOfQ; // Maximum number of bits of the value of Q28132814BOOLEAN isSafePrimeGroup; // Boolean indicating if this is a Safe Prime group2815UINT32 nMinBitsPriv; // Minimum number of bits to be used in private keys for this group2816// This only applies to named Safe Prime groups where this is related to the security strength2817// i.e. this corresponds to 2s in SP800-56arev3 5.6.1.1.1 / 5.6.2.1.22818UINT32 nDefaultBitsPriv; // Default number of bits used in private keys for this group2819// Normally equals nBitsOfQ, but may be further restricted (i.e. for named Safe Prime groups)2820// i.e. this corresponds to a default value of N in SP800-56arev3 5.6.1.1.1 / 5.6.2.1.228212822UINT32 nBitsOfSeed; // Number of bits of the seed used for generation (seedlen in FIPS 186-3)2823UINT32 cbSeed; // Number of bytes of the seed, equal to ceil(nBitsOfSeed/8)28242825SYMCRYPT_DLGROUP_FIPS eFipsStandard; // Code specifying the FIPS standard used to create the keys. If 0 the group is unverified.28262827PCSYMCRYPT_HASH pHashAlgorithm; // Hash algorithm used for the generation of parameters2828UINT32 dwGenCounter; // Number of iterations used for the generation of parameters2829BYTE bIndexGenG; // Index for the generation of generator G (FIPS 186-3) (Always 1 for now)28302831PBYTE pbQ; // SYMCRYPT_ASYM_ALIGN'ed buffer that points to the memory allocated for modulus Q28322833PSYMCRYPT_MODULUS pmP; // Pointer to the prime P2834PSYMCRYPT_MODULUS pmQ; // Pointer to the prime Q28352836PSYMCRYPT_MODELEMENT peG; // Pointer to the generator G28372838PBYTE pbSeed; // Buffer that will hold the seed (this is padded at the end so that the entire structure2839// has size a multiple of SYMCRYPT_ASYM_ALIGN_VALUE)28402841SYMCRYPT_MAGIC_FIELD28422843// P2844// Q2845// G2846// Seed2847} SYMCRYPT_DLGROUP;2848typedef SYMCRYPT_DLGROUP * PSYMCRYPT_DLGROUP;2849typedef const SYMCRYPT_DLGROUP * PCSYMCRYPT_DLGROUP;28502851//2852// DLKEY type2853//2854typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_DLKEY {2855UINT32 fAlgorithmInfo; // Tracks which algorithms the key can be used in2856// Also tracks which per-key selftests have been performed on this key2857// A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_DLKEY_*, and2858// SYMCRYPT_PCT_* values28592860BOOLEAN fHasPrivateKey; // Set to true if there is a private key set2861BOOLEAN fPrivateModQ; // Set to true if the private key is at most Q-1, otherwise it is at most P-22862UINT32 nBitsPriv; // Number of bits used in private keys28632864PCSYMCRYPT_DLGROUP pDlgroup; // Handle to the group which created the key28652866PBYTE pbPrivate; // SYMCRYPT_ASYM_ALIGN'ed buffer that points to the memory allocated for the private key28672868PSYMCRYPT_MODELEMENT pePublicKey; // Public key (modelement modulo P)2869PSYMCRYPT_INT piPrivateKey; // Private key (integer up to 2^nBitsPriv-1, Q-1 or P-2)28702871SYMCRYPT_MAGIC_FIELD28722873// PublicKey2874// PrivateKey // The size of this must always be the same as the size of P2875} SYMCRYPT_DLKEY;2876typedef SYMCRYPT_DLKEY * PSYMCRYPT_DLKEY;2877typedef const SYMCRYPT_DLKEY * PCSYMCRYPT_DLKEY;28782879//2880// Elliptic Curve Function Types2881//28822883#define SYMCRYPT_ECPOINT_FORMAT_MAX_LENGTH 4 // Number of MODELEMENTs for the largest ECPOINT format28842885// Coordinate representations for ECPOINTs2886// NOTE: The value masked with 0xf gives you the number of coordinates2887typedef enum _SYMCRYPT_ECPOINT_COORDINATES {2888SYMCRYPT_ECPOINT_COORDINATES_INVALID = 0x00, // Invalid point representation2889SYMCRYPT_ECPOINT_COORDINATES_SINGLE = 0x11, // Representation with only X2890SYMCRYPT_ECPOINT_COORDINATES_AFFINE = 0x22, // Affine representation (X,Y)2891SYMCRYPT_ECPOINT_COORDINATES_PROJECTIVE = 0x33, // Three equally-sized values where the triple (X,Y,Z) represents the affine point (X/Z, Y/Z)2892SYMCRYPT_ECPOINT_COORDINATES_JACOBIAN = 0x43, // Three equally-sized values where the triple (X,Y,Z) represents the affine point (X/Z^2, Y/Z^3)2893SYMCRYPT_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*Z2894SYMCRYPT_ECPOINT_COORDINATES_SINGLE_PROJECTIVE = 0x62, // Two equally-sized values where (X,Z) represents the point (X/Z)2895} SYMCRYPT_ECPOINT_COORDINATES;28962897#define SYMCRYPT_INTERNAL_NUMOF_COORDINATES( _eCoordinates ) ((_eCoordinates) & 0xf)289828992900//2901// Curve-type-dependent information2902//29032904// Short-Weierstrass29052906#define SYMCRYPT_ECURVE_SW_DEF_WINDOW (6) // Default window size for the windowed methods29072908#define SYMCRYPT_ECURVE_SW_MAX_NPRECOMP_POINTS (64) // Maximum number of precomputed points29092910typedef struct _SYMCRYPT_ECURVE_INFO_PRECOMP {2911UINT32 window; // Window size2912UINT32 nPrecompPoints; // Number of precomputed points2913UINT32 nRecodedDigits; // Number of recoded digits2914PSYMCRYPT_ECPOINT poPrecompPoints[SYMCRYPT_ECURVE_SW_MAX_NPRECOMP_POINTS];2915// Table of pointers to precomputed powers of the distinguished point2916} SYMCRYPT_ECURVE_INFO_PRECOMP;29172918//2919// ECURVE object2920//29212922#define SYMCRYPT_ECURVE_MIN_BITSIZE_FMOD (32)2923#define SYMCRYPT_ECURVE_MIN_BITSIZE_GORD (32)2924#define SYMCRYPT_ECURVE_MAX_COFACTOR_POWER (8)2925// Minimum (maximum for cofactor) allowable bit sizes for imported2926// parameters for field modulus, group order of curve (and cofactor).29272928#define SYMCRYPT_INTERNAL_ECURVE_VERSION_LATEST 129292930typedef enum _SYMCRYPT_INTERNAL_ECURVE_TYPE {2931SYMCRYPT_INTERNAL_ECURVE_TYPE_SHORT_WEIERSTRASS = 1,2932SYMCRYPT_INTERNAL_ECURVE_TYPE_TWISTED_EDWARDS = 2,2933SYMCRYPT_INTERNAL_ECURVE_TYPE_MONTGOMERY = 3,2934SYMCRYPT_INTERNAL_ECURVE_TYPE_SHORT_WEIERSTRASS_AM3 = 4,// This type is a specialization of Short-Weierstrass when A == -32935// This condition is detected and used for all NIST prime curves2936} SYMCRYPT_INTERNAL_ECURVE_TYPE;29372938C_ASSERT((UINT32)SYMCRYPT_INTERNAL_ECURVE_TYPE_SHORT_WEIERSTRASS == (UINT32)SYMCRYPT_ECURVE_TYPE_SHORT_WEIERSTRASS );2939C_ASSERT((UINT32)SYMCRYPT_INTERNAL_ECURVE_TYPE_TWISTED_EDWARDS == (UINT32)SYMCRYPT_ECURVE_TYPE_TWISTED_EDWARDS );2940C_ASSERT((UINT32)SYMCRYPT_INTERNAL_ECURVE_TYPE_MONTGOMERY == (UINT32)SYMCRYPT_ECURVE_TYPE_MONTGOMERY );29412942typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_ECURVE {2943UINT32 version; // Version #2944SYMCRYPT_INTERNAL_ECURVE_TYPE2945type; // Internal type of the curve2946SYMCRYPT_ECPOINT_COORDINATES2947eCoordinates; // Default representation of the EC points29482949UINT32 FModBitsize; // Bitsize of the field modulus2950UINT32 FModDigits; // Number of digits of the field modulus2951UINT32 FModBytesize; // Bytesize of the field modulus (specified in the curve parameters as cbFieldLength)29522953UINT32 GOrdBitsize; // Bitsize of the (sub)group order2954UINT32 GOrdDigits; // Number of digits of the (sub)group order2955UINT32 GOrdBytesize; // Bytesize of the (sub)group order (specified in the curve parameters as cbSubgroupOrder)29562957UINT32 cbModElement; // (Internal) bytesize of one mod element29582959UINT32 cbAlloc; // Bytesize of the total curve blob29602961UINT32 cbScratchCommon; // Size of scratch space for common ecurve operations2962UINT32 cbScratchScalar; // Size of constant scratch space for scalar ecurve operations (without the nPoints dependence)2963UINT32 cbScratchScalarMulti; // Dependence of scratch space for scalar ecurve operations from nPoints2964UINT32 cbScratchGetSetValue; // Size of scratch space for get set value ecpoint operations2965UINT32 cbScratchEckey; // Size of scratch space for eckey operations29662967UINT32 coFactorPower; // The cofactor of the curve will be equal to 2^coFactorPower29682969// Parameters V2 Extensions2970UINT32 PrivateKeyDefaultFormat;2971UINT32 HighBitRestrictionNumOfBits;2972UINT32 HighBitRestrictionPosition;2973UINT32 HighBitRestrictionValue;29742975union {29762977SYMCRYPT_ECURVE_INFO_PRECOMP sw; // Info for short Weierstrass curves (only the precomputation parameters are needed now)29782979} info; // Precomputed information related to each curve29802981PSYMCRYPT_MODULUS FMod; // Field modulus2982PSYMCRYPT_MODULUS GOrd; // Order of the subgroup29832984PSYMCRYPT_MODELEMENT A; // Parameter A2985PSYMCRYPT_MODELEMENT B; // Parameter B2986PSYMCRYPT_ECPOINT G; // Distinguished point (generator of the subgroup)2987PSYMCRYPT_INT H; // Cofactor of the curve29882989SYMCRYPT_MAGIC_FIELD29902991// FMod2992// A2993// B2994// GOrd2995// H2996// G2997} SYMCRYPT_ECURVE;2998typedef SYMCRYPT_ECURVE * PSYMCRYPT_ECURVE;2999typedef const SYMCRYPT_ECURVE * PCSYMCRYPT_ECURVE;30003001#define SYMCRYPT_INTERNAL_ECPOINT_COORDINATE_OFFSET( _pCurve, _ord ) ( sizeof(SYMCRYPT_ECPOINT) + (_ord) * (_pCurve)->cbModElement )3002#define SYMCRYPT_INTERNAL_ECPOINT_COORDINATE( _ord, _pCurve, _pEcpoint ) (PSYMCRYPT_MODELEMENT)( (PBYTE)(_pEcpoint) + SYMCRYPT_INTERNAL_ECPOINT_COORDINATE_OFFSET( (_pCurve), _ord ) )30033004// Convenience macros to make adding internal specializations easier3005#define SYMCRYPT_CURVE_IS_SHORT_WEIERSTRASS_TYPE( _pCurve ) \3006( _pCurve->type == SYMCRYPT_INTERNAL_ECURVE_TYPE_SHORT_WEIERSTRASS || \3007_pCurve->type == SYMCRYPT_INTERNAL_ECURVE_TYPE_SHORT_WEIERSTRASS_AM3 )30083009#define SYMCRYPT_CURVE_IS_TWISTED_EDWARDS_TYPE( _pCurve ) \3010( _pCurve->type == SYMCRYPT_INTERNAL_ECURVE_TYPE_TWISTED_EDWARDS )30113012#define SYMCRYPT_CURVE_IS_MONTGOMERY_TYPE( _pCurve ) \3013( _pCurve->type == SYMCRYPT_INTERNAL_ECURVE_TYPE_MONTGOMERY )30143015//3016// Scratch space sizes for ECURVE operations3017//3018// Overflow protection is enforced when creating the ECURVE objects on3019// the cbScratchCommon, cbScratchScalar, cbScratchScalarMulti, and cbScratchEckey fields.3020//3021// All of them are upper bounded by 2^26 (see SymCrypt<CurveType>FillScratchSpaces functions)3022// and since _nPoints is bounded by SYMCRYPT_ECURVE_MULTI_SCALAR_MUL_MAX_NPOINTS = 2, all3023// the macros are bounded by 2^27.3024//30253026#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_COMMON_ECURVE_OPERATIONS( _pCurve ) ( (_pCurve)->cbScratchCommon)3027#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_SCALAR_ECURVE_OPERATIONS( _pCurve, _nPoints ) ( (_pCurve)->cbScratchScalar + \3028(_nPoints) * (_pCurve)->cbScratchScalarMulti )3029#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_GETSET_VALUE_ECURVE_OPERATIONS( _pCurve ) ( (_pCurve)->cbScratchGetSetValue)3030#define SYMCRYPT_INTERNAL_SCRATCH_BYTES_FOR_ECKEY_ECURVE_OPERATIONS( _pCurve ) ( (_pCurve)->cbScratchEckey)30313032typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_ECPOINT {3033BOOLEAN normalized; // A flag specifying whether the point is normalized or not. This flag3034// makes sense only for PROJECTIVE, JACOBIAN, EXTENDED_PROJECTIVE, and3035// SINGLE_PROJECTIVE coordinates. If set to TRUE (non-zero), it means3036// that the Z coordinate of the point is equal to 1.3037PCSYMCRYPT_ECURVE pCurve; // Handle to the curve which the point is on. Only used in CHKed builds for ASSERTs3038SYMCRYPT_MAGIC_FIELD3039// An array of MODELEMENTs. The total size will depend on the MODELEMENT size and the number of MODELEMENTs.3040} SYMCRYPT_ECPOINT, *PSYMCRYPT_ECPOINT;3041typedef const SYMCRYPT_ECPOINT * PCSYMCRYPT_ECPOINT;30423043typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_ECKEY {3044UINT32 fAlgorithmInfo; // Tracks which algorithms the key can be used in3045// Also tracks which per-key selftests have been performed on this key3046// A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_ECKEY_*, and3047// SYMCRYPT_PCT_* values3048BOOLEAN hasPrivateKey; // Set to true if there is a private key set3049PCSYMCRYPT_ECURVE pCurve; // Handle to the curve which created the key30503051PSYMCRYPT_ECPOINT poPublicKey; // Public key (ECPOINT)3052PSYMCRYPT_INT piPrivateKey; // Private key30533054SYMCRYPT_MAGIC_FIELD30553056// PublicKey3057// PrivateKey3058} SYMCRYPT_ECKEY;3059typedef SYMCRYPT_ECKEY * PSYMCRYPT_ECKEY;3060typedef const SYMCRYPT_ECKEY * PCSYMCRYPT_ECKEY;30613062SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_802_11_SAE_CUSTOM_STATE {3063PSYMCRYPT_ECURVE pCurve;3064PCSYMCRYPT_MAC macAlgorithm;3065PSYMCRYPT_MODELEMENT peRand;3066PSYMCRYPT_MODELEMENT peMask;3067PSYMCRYPT_ECPOINT poPWE;3068BYTE counter;3069};30703071//3072// XMSS3073//30743075typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_XMSS_PARAMS3076{3077PCSYMCRYPT_HASH hash; // hash function3078UINT32 id; // algorithm identifier3079UINT32 cbHashOutput; // hash function output size, must be less than or equal to hash->resultSize3080UINT32 nWinternitzWidth;// Winternitz coefficient, width of digits in bits (chain length = 2^nWinternitzWidth)3081UINT32 nTotalTreeHeight;// number of layers times the tree height of one layer (each layer has the same height)3082UINT32 nLayers; // hyper-tree layers, 1 for single tree3083UINT32 cbPrefix; // length of the domain separator prefix in PRFs30843085//3086// The following are derived from the above3087//3088UINT32 len1; // number of w-bit digits in the hash output to be signed ( len1 = ceil(8n / w) )3089UINT32 len2; // number of w-bit digits in the checksum3090UINT32 len; // len1 + len23091UINT32 nLayerHeight; // tree height of a single layer (h / d)3092UINT32 cbIdx; // size of leaf counter in bytes (for single trees cbIdx = 4)3093UINT32 nLeftShift32; // left shift count to align the checksum digits to MSB of a 32-bit word30943095BYTE Reserved[16]; // Reserved for future use3096} SYMCRYPT_XMSS_PARAMS;30973098typedef SYMCRYPT_XMSS_PARAMS* PSYMCRYPT_XMSS_PARAMS;3099typedef const SYMCRYPT_XMSS_PARAMS* PCSYMCRYPT_XMSS_PARAMS;31003101struct _SYMCRYPT_XMSS_KEY;3102typedef struct _SYMCRYPT_XMSS_KEY SYMCRYPT_XMSS_KEY;3103typedef SYMCRYPT_XMSS_KEY* PSYMCRYPT_XMSS_KEY;3104typedef const SYMCRYPT_XMSS_KEY* PCSYMCRYPT_XMSS_KEY;310531063107//==========================================================================3108// LMS internal structures3109//==========================================================================31103111typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_LMS_PARAMS3112{3113// algorithm ID of the LMS signature scheme3114UINT32 lmsAlgID;31153116// algorithm ID of the LM-OTS signature scheme3117UINT32 lmsOtsAlgID;31183119// hash function pointer to be used as part of the LMS operations3120PCSYMCRYPT_HASH pLmsHashFunction;31213122// the height of the LMS tree. There are 2^h leaves in the tree - h3123UINT32 nTreeHeight;31243125// the number of bytes for each tree node, equals to the output length of the hash function - m, n3126UINT32 cbHashOutput;31273128// Winternitz coefficient, width of digits in bits (chain length = 2^w) - w3129UINT32 nWinternitzChainWidth;31303131// the number of n-byte string elements that make up the LM-OTS signature - p3132UINT32 nByteStringCount;31333134// the number of left-shift bits used in the checksum function Cksm - ls3135UINT32 nChecksumLShiftBits;3136} SYMCRYPT_LMS_PARAMS;3137typedef SYMCRYPT_LMS_PARAMS* PSYMCRYPT_LMS_PARAMS;3138typedef const SYMCRYPT_LMS_PARAMS* PCSYMCRYPT_LMS_PARAMS;31393140struct _SYMCRYPT_LMS_KEY;3141typedef struct _SYMCRYPT_LMS_KEY SYMCRYPT_LMS_KEY;3142typedef SYMCRYPT_LMS_KEY* PSYMCRYPT_LMS_KEY;3143typedef const SYMCRYPT_LMS_KEY* PCSYMCRYPT_LMS_KEY;31443145#ifndef _PREFAST_3146#if SYMCRYPT_CPU_X863147#pragma warning(pop)3148#endif3149#endif3150315131523153//////////////////////////////////////////////////////////3154//3155// Environment macros3156//31573158#ifdef __cplusplus3159#define SYMCRYPT_EXTERN_C extern "C" {3160#define SYMCRYPT_EXTERN_C_END }3161#else3162#define SYMCRYPT_EXTERN_C3163#define SYMCRYPT_EXTERN_C_END3164#endif31653166//3167// Callers of SymCrypt should NOT depend on the function names in these macros.3168// The definition of these macros can change in future releases of the library.3169//31703171#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD643172typedef struct _SYMCRYPT_EXTENDED_SAVE_DATA SYMCRYPT_EXTENDED_SAVE_DATA, *PSYMCRYPT_EXTENDED_SAVE_DATA;31733174#define SYMCRYPT_ENVIRONMENT_DEFS_SAVEYMM( envName ) \3175SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSaveYmmEnv##envName( _Out_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ); \3176SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSaveYmm( _Out_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ) \3177{ return SymCryptSaveYmmEnv##envName( pSaveArea ); } \3178\3179VOID SYMCRYPT_CALL SymCryptRestoreYmmEnv##envName( _Inout_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ); \3180VOID SYMCRYPT_CALL SymCryptRestoreYmm( _Inout_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ) \3181{ SymCryptRestoreYmmEnv##envName( pSaveArea ); } \31823183#define SYMCRYPT_ENVIRONMENT_DEFS_SAVEXMM( envName ) \3184SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSaveXmmEnv##envName( _Out_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ); \3185SYMCRYPT_ERROR SYMCRYPT_CALL SymCryptSaveXmm( _Out_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ) \3186{ return SymCryptSaveXmmEnv##envName( pSaveArea ); } \3187\3188VOID SYMCRYPT_CALL SymCryptRestoreXmmEnv##envName( _Inout_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ); \3189VOID SYMCRYPT_CALL SymCryptRestoreXmm( _Inout_ PSYMCRYPT_EXTENDED_SAVE_DATA pSaveArea ) \3190{ SymCryptRestoreXmmEnv##envName( pSaveArea ); } \319131923193#else31943195#define SYMCRYPT_ENVIRONMENT_DEFS_SAVEYMM( envName )3196#define SYMCRYPT_ENVIRONMENT_DEFS_SAVEXMM( envName )31973198#endif31993200// Environment forwarding functions.3201// CPUIDEX is only forwarded on CPUs that have it.3202#if SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_X863203#define SYMCRYPT_ENVIRONMENT_FORWARD_CPUIDEX( envName ) \3204VOID SYMCRYPT_CALL SymCryptCpuidExFuncEnv##envName( int cpuInfo[4], int function_id, int subfunction_id ); \3205VOID SYMCRYPT_CALL SymCryptCpuidExFunc( int cpuInfo[4], int function_id, int subfunction_id ) \3206{ SymCryptCpuidExFuncEnv##envName( cpuInfo, function_id, subfunction_id ); }3207#else3208#define SYMCRYPT_ENVIRONMENT_FORWARD_CPUIDEX( envName )3209#endif32103211#define SYMCRYPT_ENVIRONMENT_DEFS( envName ) \3212SYMCRYPT_EXTERN_C \3213VOID SYMCRYPT_CALL SymCryptInitEnv##envName( UINT32 version ); \3214VOID SYMCRYPT_CALL SymCryptInit(void) \3215{ SymCryptInitEnv##envName( SYMCRYPT_API_VERSION ); } \3216\3217_Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatalEnv##envName( UINT32 fatalCode ); \3218_Analysis_noreturn_ VOID SYMCRYPT_CALL SymCryptFatal( UINT32 fatalCode ) \3219{ SymCryptFatalEnv##envName( fatalCode ); } \3220SYMCRYPT_CPU_FEATURES SYMCRYPT_CALL SymCryptCpuFeaturesNeverPresentEnv##envName(void); \3221SYMCRYPT_CPU_FEATURES SYMCRYPT_CALL SymCryptCpuFeaturesNeverPresent(void) \3222{ return SymCryptCpuFeaturesNeverPresentEnv##envName(); } \3223\3224SYMCRYPT_ENVIRONMENT_DEFS_SAVEXMM( envName ) \3225SYMCRYPT_ENVIRONMENT_DEFS_SAVEYMM( envName ) \3226\3227VOID SYMCRYPT_CALL SymCryptTestInjectErrorEnv##envName( PBYTE pbBuf, SIZE_T cbBuf ); \3228VOID SYMCRYPT_CALL SymCryptInjectError( PBYTE pbBuf, SIZE_T cbBuf ) \3229{ SymCryptTestInjectErrorEnv##envName( pbBuf, cbBuf ); } \3230SYMCRYPT_ENVIRONMENT_FORWARD_CPUIDEX( envName ) \3231SYMCRYPT_EXTERN_C_END32323233//3234// To avoid hard-do-diagnose mistakes, we skip defining environment macros in those cases where we3235// know they cannot or should not be used.3236//32373238#define SYMCRYPT_ENVIRONMENT_GENERIC SYMCRYPT_ENVIRONMENT_DEFS( Generic )32393240#if defined(EFI) | defined(PCAT) | defined(DIRECT)3241#define SYMCRYPT_ENVIRONMENT_WINDOWS_BOOTLIBRARY SYMCRYPT_ENVIRONMENT_DEFS( WindowsBootlibrary )3242#endif32433244//3245// There are no defined symbols that we can use to detect that we are in debugger code3246// But this is unlikely to be misused.3247//3248#define SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELDEBUGGER SYMCRYPT_ENVIRONMENT_DEFS( WindowsKernelDebugger )3249325032513252#define SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_LEGACY SYMCRYPT_ENVIRONMENT_GENERIC32533254#ifdef NTDDI_VERSION3255#if (NTDDI_VERSION >= NTDDI_WIN7)3256#define SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_WIN7_N_LATER SYMCRYPT_ENVIRONMENT_DEFS( WindowsKernelmodeWin7nLater )3257#endif32583259#if (NTDDI_VERSION >= NTDDI_WINBLUE)3260#define SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_WIN8_1_N_LATER SYMCRYPT_ENVIRONMENT_DEFS( WindowsKernelmodeWin8_1nLater )3261#endif32623263#define SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_LATEST SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_WIN8_1_N_LATER3264326532663267#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_LEGACY SYMCRYPT_ENVIRONMENT_GENERIC32683269#if (NTDDI_VERSION >= NTDDI_WIN7)3270#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN7_N_LATER SYMCRYPT_ENVIRONMENT_DEFS( WindowsUsermodeWin7nLater )3271#endif32723273#if (NTDDI_VERSION >= NTDDI_WINBLUE)3274#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN8_1_N_LATER SYMCRYPT_ENVIRONMENT_DEFS( WindowsUsermodeWin8_1nLater )3275#endif32763277#if (NTDDI_VERSION >= NTDDI_WIN10)3278#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN10_SGX SYMCRYPT_ENVIRONMENT_DEFS( Win10Sgx )3279#endif3280#endif // NTDDI_VERSION32813282#define SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_LATEST SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN8_1_N_LATER328332843285#define SYMCRYPT_ENVIRONMENT_POSIX_USERMODE SYMCRYPT_ENVIRONMENT_DEFS( PosixUsermode )32863287// For backwards compatibility with previous macro name3288#define SYMCRYPT_ENVIRONMENT_LINUX_USERMODE SYMCRYPT_ENVIRONMENT_POSIX_USERMODE328932903291#define SYMCRYPT_ENVIRONMENT_OPTEE_TA SYMCRYPT_ENVIRONMENT_DEFS( OpteeTa )32923293//////////////////////////////////////////////////////////3294//3295// SymCryptWipe & SymCryptWipeKnownSize3296//32973298VOID3299SYMCRYPT_CALL3300SymCryptWipe(3301_Out_writes_bytes_(cbData) PVOID pbData,3302SIZE_T cbData);33033304#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM | SYMCRYPT_CPU_ARM6433053306//3307// If the known size is large we call the generic wipe function anyway.3308// For small known sizes we perform the wipe inline.3309// This is a tradeoff between speed and code size and there are diminishing returns to supporting3310// increasingly large sizes.3311// We currently put the limit at ~8 native writes, which varies by platform.3312//3313#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_ARM3314#define SYMCRYPT_WIPE_FUNCTION_LIMIT (32) // If this is increased beyond 127 the code below must be updated.3315#elif SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM643316#define SYMCRYPT_WIPE_FUNCTION_LIMIT (64) // If this is increased beyond 127 the code below must be updated.3317#else3318#error ??3319#endif33203321//3322// The buffer analysis code doesn't understand our optimized in-line wiping code3323// well enough to conclude it is safe.3324//3325#pragma prefast(push)3326#pragma prefast( disable: 26001 )33273328FORCEINLINE3329VOID3330SYMCRYPT_CALL3331#pragma prefast( suppress: 6101, "Logic why this properly initializes the pbData buffer is too complicated for prefast" )3332SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)3333{3334volatile BYTE * pb = (volatile BYTE *)pbData;33353336if (cbData > SYMCRYPT_WIPE_FUNCTION_LIMIT)3337{3338SymCryptWipe(pbData, cbData);3339}3340else3341{3342//3343// We assume that pb is aligned, so we wipe from the end to the front to keep alignment.3344//3345if (cbData & 1)3346{3347cbData--;3348SYMCRYPT_INTERNAL_FORCE_WRITE8((volatile BYTE *)&pb[cbData], 0);3349}3350if (cbData & 2)3351{3352cbData -= 2;3353SYMCRYPT_INTERNAL_FORCE_WRITE16((volatile UINT16 *)&pb[cbData], 0);3354}3355if (cbData & 4)3356{3357cbData -= 4;3358SYMCRYPT_INTERNAL_FORCE_WRITE32((volatile UINT32 *)&pb[cbData], 0);3359}3360if (cbData & 8)3361{3362cbData -= 8;3363SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);3364}3365if (cbData & 16)3366{3367cbData -= 16;3368SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);3369SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);3370}3371if (cbData & 32)3372{3373cbData -= 32;3374SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);3375SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);3376SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);3377SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);3378}3379#if SYMCRYPT_WIPE_FUNCTION_LIMIT >= 643380if (cbData & 64)3381{3382cbData -= 64;3383SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData], 0);3384SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 8], 0);3385SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 16], 0);3386SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 24], 0);3387SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 32], 0);3388SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 40], 0);3389SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 48], 0);3390SYMCRYPT_INTERNAL_FORCE_WRITE64((volatile UINT64 *)&pb[cbData + 56], 0);3391}3392#endif3393}3394}33953396#pragma prefast(pop)33973398#else // Platform switch for SymCryptWipeKnownSize33993400FORCEINLINE3401VOID3402SYMCRYPT_CALL3403SymCryptWipeKnownSize(_Out_writes_bytes_(cbData) PVOID pbData, SIZE_T cbData)3404{3405SymCryptWipe(pbData, cbData);3406}34073408#endif // Platform switch for SymCryptWipeKnownSize34093410#define SYMCRYPT_FIPS_ASSERT(x) { if(!(x)){ SymCryptFatal('FIPS'); } }34113412// Flags for FIPS on-demand selftests. When an on-demand selftest succeeds, the corresponding flag3413// will be set in g_SymCryptFipsSelftestsPerformed. Other selftests are performed automatically3414// when the module is loaded, so they don't have a corresponding flag.3415typedef enum _SYMCRYPT_SELFTEST_ALGORITHM {3416SYMCRYPT_SELFTEST_ALGORITHM_NONE = 0x0,3417SYMCRYPT_SELFTEST_ALGORITHM_STARTUP = 0x1,3418SYMCRYPT_SELFTEST_ALGORITHM_DSA = 0x2,3419SYMCRYPT_SELFTEST_ALGORITHM_ECDSA = 0x4,3420SYMCRYPT_SELFTEST_ALGORITHM_RSA = 0x8,3421SYMCRYPT_SELFTEST_ALGORITHM_DH = 0x10,3422SYMCRYPT_SELFTEST_ALGORITHM_ECDH = 0x20,3423SYMCRYPT_SELFTEST_ALGORITHM_MLKEM = 0x40,3424SYMCRYPT_SELFTEST_ALGORITHM_XMSS = 0x80,3425SYMCRYPT_SELFTEST_ALGORITHM_LMS = 0x100,3426SYMCRYPT_SELFTEST_ALGORITHM_MLDSA = 0x200,3427} SYMCRYPT_SELFTEST_ALGORITHM;34283429// Takes values which are some bitwise OR combination of SYMCRYPT_SELFTEST_ALGORITHM values3430// Specified as UINT32 as we will update with 32 bit atomics, and compilers may choose to make enum3431// types smaller than 32 bits.3432extern UINT32 g_SymCryptFipsSelftestsPerformed;34333434UINT323435SYMCRYPT_CALL3436SymCryptFipsGetSelftestsPerformed(void);3437// Returns current value of g_SymCryptFipsSelftestsPerformed so callers may inspect which FIPS3438// algorithm selftests have run34393440// Flags for per-key selftests.3441// When an asymmetric key is generated or imported, and SYMCRYPT_FLAG_KEY_NO_FIPS is not specified,3442// some selftests must be performed on the key, before its operational use in an algorithm, to3443// comply with FIPS.3444// The algorithms the key may be used in will be tracked in the key's fAlgorithmInfo field, as a3445// bitwise OR of SYMCRYPT_FLAG_<keytype>_<algorithm> (e.g. SYMCRYPT_FLAG_DLKEY_DH).3446// This field will also track which per-key selftests have been run on the key using the below flags3447// We want to track which selftests have been run independently of which algorithms the key may be3448// used in as in some scenarios at key generation / import time we may not know what algorithm the3449// key will actually be used in. Tracking the run per-key selftests in fAlgorithmInfo allows us to3450// defer running expensive tests until we know they are required (e.g. if we generate an Eckey which3451// may be used in ECDH or ECDSA, and only use it for ECDH, the ECDSA PCT is deferred until we first3452// attempt to use the key in ECDSA, or export the private key).3453//3454// For clarity, SYMCRYPT_PCT_* should be used instead of SYMCRYPT_SELFTEST_KEY_* going forward.3455// The latter is retained for compatibility with existing code, but may be removed in a future3456// breaking change.34573458// Dlkey selftest flags3459// DSA Pairwise Consistency Test to be run on generated keys3460#define SYMCRYPT_SELFTEST_KEY_DSA (0x1)3461#define SYMCRYPT_PCT_DSA SYMCRYPT_SELFTEST_KEY_DSA34623463// Eckey selftest flags3464// ECDSA Pairwise Consistency Test to be run on generated keys3465#define SYMCRYPT_SELFTEST_KEY_ECDSA (0x1)3466#define SYMCRYPT_PCT_ECDSA SYMCRYPT_SELFTEST_KEY_ECDSA34673468// Rsakey selftest flags3469// RSA Pairwise Consistency Test to be run on generated keys3470#define SYMCRYPT_SELFTEST_KEY_RSA_SIGN (0x1)3471#define SYMCRYPT_PCT_RSA_SIGN SYMCRYPT_SELFTEST_KEY_RSA_SIGN34723473UINT323474SYMCRYPT_CALL3475SymCryptDeprecatedStatusIndicator(PBYTE pbOutput, UINT32 cbOutput);3476//3477// Returns the FIPS Approved Services Status Indicator as an ASCII string.3478// This API is required to satisfy FIPS 140-3 requirements, but is *not* recommended3479// to be used in production code. It should be considered unstable,3480// and may be removed at any time.3481//3482// The output string will be copied to pbOutput if the size of the buffer3483// cbOutput is large enough. The function returns the required buffer size3484// when pbOutput is passed as NULL. If pbOutput is not NULL, the function3485// returns the number of bytes copied to pbOutput.3486//3487348834893490typedef enum _SYMCRYPT_SI_TYPE {34913492// Algorithm types (specific algorithms are represented as a bitmask of a type)3493SYMCRYPT_SI_TYPE_CIPHER = 0x01,3494SYMCRYPT_SI_TYPE_HASH = 0x02,3495SYMCRYPT_SI_TYPE_MAC = 0x03,3496SYMCRYPT_SI_TYPE_KDF = 0x04,3497SYMCRYPT_SI_TYPE_DRBG = 0x05,3498SYMCRYPT_SI_TYPE_ASYM_ALG = 0x06,3499SYMCRYPT_SI_TYPE_KAS = 0x07,3500SYMCRYPT_SI_TYPE_KEM = 0x08,35013502// Other types where elements are a bitmask3503SYMCRYPT_SI_TYPE_ECURVE = 0x40,3504SYMCRYPT_SI_TYPE_KAS_SCHEME = 0x41,3505SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP = 0x42,35063507// Non-bitmask types3508SYMCRYPT_SI_TYPE_INTRANGE = 0x80,3509SYMCRYPT_SI_TYPE_INTPAIR = 0x81,3510SYMCRYPT_SI_TYPE_SIZERANGE = 0x82,35113512SYMCRYPT_SI_TYPE_MAX = 0xFF3513} SYMCRYPT_SI_TYPE;35143515#define SYMCRYPT_SI_CREATE_ID(type, index) (((UINT64)(type) << 56) + (1ULL << (index)))35163517#define SYMCRYPT_SI_INTBITS ((64 - 8) / 2) // 8-bits for type, remaining bits shared by two integers3518#define SYMCRYPT_SI_INTMASK ((1ULL << SYMCRYPT_SI_INTBITS) - 1) // typically should be 0x0FFFFFFF with 28 1s3519#define SYMCRYPT_SI_INTPACK(High, Low) (((((UINT64)High) & SYMCRYPT_SI_INTMASK) << SYMCRYPT_SI_INTBITS) | (((UINT64)Low) & SYMCRYPT_SI_INTMASK))3520#define SYMCRYPT_SI_INTUNPACKLO(X) ((X) & SYMCRYPT_SI_INTMASK)3521#define SYMCRYPT_SI_INTUNPACKHI(X) (((X) >> SYMCRYPT_SI_INTBITS) & SYMCRYPT_SI_INTMASK)35223523#define SYMCRYPT_SI_INTRANGE(Low, High) (((UINT64)SYMCRYPT_SI_TYPE_INTRANGE << 56) | SYMCRYPT_SI_INTPACK(High, Low))3524#define SYMCRYPT_SI_INTPAIR(X, Y) (((UINT64)SYMCRYPT_SI_TYPE_INTPAIR << 56) | SYMCRYPT_SI_INTPACK(Y, X))3525#define SYMCRYPT_SI_SIZERANGE(Low, High) (((UINT64)SYMCRYPT_SI_TYPE_SIZERANGE << 56) | SYMCRYPT_SI_INTPACK(High, Low))35263527#define SYMCRYPT_SI_CHECK_INT(L) C_ASSERT(L <= SYMCRYPT_SI_INTMASK)35283529#define SYMCRYPT_SI_KEYBITS(L) SYMCRYPT_SI_SIZERANGE(L, L)3530#define SYMCRYPT_SI_MODULUS(L) SYMCRYPT_SI_SIZERANGE(L, L)3531#define SYMCRYPT_SI_DSAPARAMS(N, L) SYMCRYPT_SI_INTPAIR(N, L)353235333534// Services3535#define SYMCRYPT_SI_SVC_ENCRYPTION 0x000000013536#define SYMCRYPT_SI_SVC_DECRYPTION 0x000000023537#define SYMCRYPT_SI_SVC_HASHING 0x000000043538#define SYMCRYPT_SI_SVC_MESSAGE_AUTHENTICATION 0x000000083539#define SYMCRYPT_SI_SVC_KEY_DERIVATION 0x000000103540#define SYMCRYPT_SI_SVC_ASYMMETRIC_KEY_GENERATION 0x000000203541#define SYMCRYPT_SI_SVC_ASYMMETRIC_KEY_VERIFICATION 0x000000803542#define SYMCRYPT_SI_SVC_RANDOM_NUMBER_GENERATION 0x000004003543#define SYMCRYPT_SI_SVC_SECRET_AGREEMENT 0x000008003544#define SYMCRYPT_SI_SVC_SIGNATURE_GENERATION 0x000010003545#define SYMCRYPT_SI_SVC_SIGNATURE_VERIFICATION 0x000020003546#define SYMCRYPT_SI_SVC_KEY_ENCAPSULATION 0x000040003547#define SYMCRYPT_SI_SVC_KEY_DECAPSULATION 0x0000800035483549// Ciphers3550#define SYMCRYPT_SI_AES_CBC SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 0)3551#define SYMCRYPT_SI_AES_CCM SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 1)3552#define SYMCRYPT_SI_AES_CFB128 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 2)3553#define SYMCRYPT_SI_AES_CFB8 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 3)3554#define SYMCRYPT_SI_AES_CTR SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 4)3555#define SYMCRYPT_SI_AES_ECB SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 5)3556#define SYMCRYPT_SI_AES_GCM SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 6)3557#define SYMCRYPT_SI_AES_XTS SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 7)3558#define SYMCRYPT_SI_RC2 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 8)3559#define SYMCRYPT_SI_RC4 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 9)3560#define SYMCRYPT_SI_CHACHA SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 10)3561#define SYMCRYPT_SI_DES SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 11)3562#define SYMCRYPT_SI_TRIPLEDES SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 12)3563#define SYMCRYPT_SI_CHACHA20 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 13)3564#define SYMCRYPT_SI_CHACHA20_POLY1305 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 14)3565#define SYMCRYPT_SI_AES_KW SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 15)3566#define SYMCRYPT_SI_AES_KWP SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_CIPHER, 16)35673568// Hash Functions3569#define SYMCRYPT_SI_MD2 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 0)3570#define SYMCRYPT_SI_MD4 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 1)3571#define SYMCRYPT_SI_MD5 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 2)3572#define SYMCRYPT_SI_SHA1 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 3)3573#define SYMCRYPT_SI_SHA2_224 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 4)3574#define SYMCRYPT_SI_SHA2_256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 5)3575#define SYMCRYPT_SI_SHA2_384 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 6)3576#define SYMCRYPT_SI_SHA2_512 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 7)3577#define SYMCRYPT_SI_SHA2_512_224 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 8)3578#define SYMCRYPT_SI_SHA2_512_256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 9)3579#define SYMCRYPT_SI_SHA3_224 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 10)3580#define SYMCRYPT_SI_SHA3_256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 11)3581#define SYMCRYPT_SI_SHA3_384 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 12)3582#define SYMCRYPT_SI_SHA3_512 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 13)3583#define SYMCRYPT_SI_SHAKE128 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 14)3584#define SYMCRYPT_SI_SHAKE256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 15)3585#define SYMCRYPT_SI_CSHAKE128 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 16)3586#define SYMCRYPT_SI_CSHAKE256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 17)3587#define SYMCRYPT_SI_MARVIN32 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_HASH, 18)35883589// MAC3590#define SYMCRYPT_SI_HMAC_MD2 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 0)3591#define SYMCRYPT_SI_HMAC_MD4 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 1)3592#define SYMCRYPT_SI_HMAC_MD5 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 2)3593#define SYMCRYPT_SI_HMAC_SHA1 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 3)3594#define SYMCRYPT_SI_HMAC_SHA2_224 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 4)3595#define SYMCRYPT_SI_HMAC_SHA2_256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 5)3596#define SYMCRYPT_SI_HMAC_SHA2_384 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 6)3597#define SYMCRYPT_SI_HMAC_SHA2_512 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 7)3598#define SYMCRYPT_SI_HMAC_SHA2_512_224 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 8)3599#define SYMCRYPT_SI_HMAC_SHA2_512_256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 9)3600#define SYMCRYPT_SI_HMAC_SHA3_224 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 10)3601#define SYMCRYPT_SI_HMAC_SHA3_256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 11)3602#define SYMCRYPT_SI_HMAC_SHA3_384 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 12)3603#define SYMCRYPT_SI_HMAC_SHA3_512 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 13)3604#define SYMCRYPT_SI_KMAC128 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 14)3605#define SYMCRYPT_SI_KMAC256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 15)3606#define SYMCRYPT_SI_AES_GMAC SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 16)3607#define SYMCRYPT_SI_AES_CMAC SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 17)3608#define SYMCRYPT_SI_AES_CBCMAC SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 18)3609#define SYMCRYPT_SI_POLY1305 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_MAC, 19)36103611// KDF3612#define SYMCRYPT_SI_HKDF SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KDF, 0)3613#define SYMCRYPT_SI_PBKDF SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KDF, 1)3614#define SYMCRYPT_SI_KDA_ONESTEP SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KDF, 2)3615#define SYMCRYPT_SI_KDF_IKEV1 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KDF, 3)3616#define SYMCRYPT_SI_KDF_IKEV2 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KDF, 4)3617#define SYMCRYPT_SI_KDF_SP800_108_CTR SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KDF, 5)3618#define SYMCRYPT_SI_KDF_SRTP SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KDF, 6)3619#define SYMCRYPT_SI_KDF_SSH SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KDF, 7)3620#define SYMCRYPT_SI_KDF_TLS SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KDF, 8)3621#define SYMCRYPT_SI_KDF_TLS_V12 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KDF, 9)36223623// DRBG3624#define SYMCRYPT_SI_CTR_DRBG_AES256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_DRBG, 0)36253626// Asymmetric Algorithms3627#define SYMCRYPT_SI_SAFE_PRIME_KEYGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 0)3628#define SYMCRYPT_SI_DSA_KEYGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 1)3629#define SYMCRYPT_SI_DSA_PQGGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 2)3630#define SYMCRYPT_SI_DSA_PQGVER SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 3)3631#define SYMCRYPT_SI_DSA_SIGVER SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 4)36323633#define SYMCRYPT_SI_ECDSA_KEYGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 5)3634#define SYMCRYPT_SI_ECDSA_KEYVER SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 6)3635#define SYMCRYPT_SI_ECDSA_SIGGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 7)3636#define SYMCRYPT_SI_ECDSA_SIGVER SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 8)3637#define SYMCRYPT_SI_ECDSA_SIGGEN_COMP SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 9)36383639#define SYMCRYPT_SI_RSA_KEYGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 10)3640#define SYMCRYPT_SI_RSA_DEC_PRIM SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 12)3641#define SYMCRYPT_SI_RSA_SIG_PRIM SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 13)3642#define SYMCRYPT_SI_RSA_SIGGEN_PKCS15 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 14)3643#define SYMCRYPT_SI_RSA_SIGGEN_PKCSPSS SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 15)3644#define SYMCRYPT_SI_RSA_SIGVER_PKCS15 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 16)3645#define SYMCRYPT_SI_RSA_SIGVER_PKCSPSS SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 17)36463647#define SYMCRYPT_SI_KAS_ECC SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 18)3648#define SYMCRYPT_SI_KAS_ECC_SSC SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 19)3649#define SYMCRYPT_SI_KAS_FFC SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 20)3650#define SYMCRYPT_SI_KAS_FFC_SSC SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 21)36513652// PQ Algorithms36533654// Asym Alg IDs for PQC algorithms in range 22-26 are replaced with more granular3655// algorithms as below.3656// Keeping this range reserved until there's a need to use it in the future.36573658#define SYMCRYPT_SI_MLDSA_KEYGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 27)3659#define SYMCRYPT_SI_MLDSA_SIGGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 28)3660#define SYMCRYPT_SI_MLDSA_SIGVER SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 29)3661#define SYMCRYPT_SI_LMS_KEYGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 30)3662#define SYMCRYPT_SI_LMS_SIGGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 31)3663#define SYMCRYPT_SI_LMS_SIGVER SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 32)3664#define SYMCRYPT_SI_XMSS_KEYGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 33)3665#define SYMCRYPT_SI_XMSS_SIGGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 34)3666#define SYMCRYPT_SI_XMSS_SIGVER SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 35)3667#define SYMCRYPT_SI_XMSS_MT_KEYGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 36)3668#define SYMCRYPT_SI_XMSS_MT_SIGGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 37)3669#define SYMCRYPT_SI_XMSS_MT_SIGVER SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ASYM_ALG, 38)36703671#define SYMCRYPT_SI_MLKEM_KEYGEN SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KEM, 0)3672#define SYMCRYPT_SI_MLKEM_ENCAPS SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KEM, 1)3673#define SYMCRYPT_SI_MLKEM_DECAPS SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KEM, 2)367436753676// Elliptic Curves3677#define SYMCRYPT_SI_ECURVE_NISTP192 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ECURVE, 0)3678#define SYMCRYPT_SI_ECURVE_NISTP224 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ECURVE, 1)3679#define SYMCRYPT_SI_ECURVE_NISTP256 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ECURVE, 2)3680#define SYMCRYPT_SI_ECURVE_NISTP384 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ECURVE, 3)3681#define SYMCRYPT_SI_ECURVE_NISTP521 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ECURVE, 4)3682#define SYMCRYPT_SI_ECURVE_NUMSP256T1 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ECURVE, 5)3683#define SYMCRYPT_SI_ECURVE_NUMSP384T1 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ECURVE, 6)3684#define SYMCRYPT_SI_ECURVE_NUMSP512T1 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ECURVE, 7)3685#define SYMCRYPT_SI_ECURVE_CURVE25519 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_ECURVE, 8)36863687// Safe Prime Groups3688#define SYMCRYPT_SI_SPG_FFDHE_2048 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP, 0)3689#define SYMCRYPT_SI_SPG_FFDHE_3072 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP, 1)3690#define SYMCRYPT_SI_SPG_FFDHE_4096 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP, 2)3691#define SYMCRYPT_SI_SPG_FFDHE_6144 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP, 3)3692#define SYMCRYPT_SI_SPG_FFDHE_8192 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP, 4)3693#define SYMCRYPT_SI_SPG_MODP_2048 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP, 5)3694#define SYMCRYPT_SI_SPG_MODP_3072 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP, 6)3695#define SYMCRYPT_SI_SPG_MODP_4096 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP, 7)3696#define SYMCRYPT_SI_SPG_MODP_6144 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP, 8)3697#define SYMCRYPT_SI_SPG_MODP_8192 SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_SAFE_PRIME_GROUP, 9)36983699// KAS Schemes3700#define SYMCRYPT_SI_SCHEME_EPHEM_UNIFIED SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KAS_SCHEME, 0)3701#define SYMCRYPT_SI_SCHEME_DH_EPHEM SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KAS_SCHEME, 1)3702#define SYMCRYPT_SI_SCHEME_DH_ONEFLOW SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KAS_SCHEME, 2)3703#define SYMCRYPT_SI_SCHEME_DH_STATIC SYMCRYPT_SI_CREATE_ID(SYMCRYPT_SI_TYPE_KAS_SCHEME, 3)370437053706UINT323707SYMCRYPT_CALL3708SymCryptDeprecatedServiceIndicator(3709UINT32 Service,3710UINT64 Alg,3711UINT64 Param1,3712UINT64 Param2,3713UINT64 Param3);3714//3715// Returns FIPS 140 Approved Services Indicator for an algorithm.3716//3717// Parameters:3718// - Service. Service identifier, one of SYMCRYPT_SI_SVC_XXX.3719// - Alg. Identifier of the algorithm for which the status is being queried. This must be3720// exactly one of the algorithm identifiers defined above.3721// - Param1, Param2, Param3. Depending on the Alg parameter, these parameters provide3722// additional information about the capabilities and parameters associated with an3723// algorithm. For each algorithm, the number and type of the parameters must be provided3724// as specified below. Any unused parameters must be passed as 0. The algorithms that require3725// parameters to be specified are listed below, the remaining algorithms do not have any parameters.3726//3727// Alg Id Param1 Param23728// ----------------------------- -------------------------------- ---------------3729// SYMCRYPT_SI_AES_XTS SYMCRYPT_SI_KEYBITS(int) -3730// SYMCRYPT_SI_DSA_PQGVER SYMCRYPT_SI_DSAPARAMS(int, int) -3731// SYMCRYPT_SI_DSA_SIGVER SYMCRYPT_SI_DSAPARAMS(int, int) -3732// SYMCRYPT_SI_ECDSA_KEYGEN SYMCRYPT_SI_ECURVE_XXX -3733// SYMCRYPT_SI_ECDSA_KEYVER SYMCRYPT_SI_ECURVE_XXX -3734// SYMCRYPT_SI_ECDSA_SIGGEN SYMCRYPT_SI_ECURVE_XXX Hash Alg Id3735// SYMCRYPT_SI_ECDSA_SIGGEN_COMP SYMCRYPT_SI_ECURVE_XXX Hash Alg Id3736// SYMCRYPT_SI_ECDSA_SIGVER SYMCRYPT_SI_ECURVE_XXX Hash Alg Id3737// SYMCRYPT_SI_RSA_DEC_PRIM SYMCRYPT_SI_MODULUS(int) -3738// SYMCRYPT_SI_RSA_KEYGEN SYMCRYPT_SI_MODULUS(int) -3739// SYMCRYPT_SI_RSA_SIGGEN_PKCS15 SYMCRYPT_SI_MODULUS(int) Hash Alg Id3740// SYMCRYPT_SI_RSA_SIGVER_PKCS15 SYMCRYPT_SI_MODULUS(int) Hash Alg Id3741// SYMCRYPT_SI_RSA_SIGGEN_PKCSPSS SYMCRYPT_SI_MODULUS(int) Hash Alg Id3742// SYMCRYPT_SI_RSA_SIGVER_PKCSPSS SYMCRYPT_SI_MODULUS(int) Hash Alg Id3743// SYMCRYPT_SI_SAFE_PRIME_KEYGEN SYMCRYPT_SI_SPG_XXX Hash Alg Id3744// SYMCRYPT_SI_HMAC_XXX SYMCRYPT_SI_KEYBITS(int) -3745// SYMCRYPT_SI_KDA_ONESTEP Hash Alg Id or MAC alg Id -3746// SYMCRYPT_SI_PBKDF MAC Alg Id -3747// SYMCRYPT_SI_KDF_SP800_108_CTR MAC Alg Id -3748// SYMCRYPT_SI_KDF_SSH Hash Alg Id -3749// SYMCRYPT_SI_TLS_V12_KDF Hash Alg Id -3750// SYMCRYPT_SI_KAS_ECC SYMCRYPT_SI_ECURVE_XXX Hash Alg Id3751// SYMCRYPT_SI_KAS_ECC_SSC SYMCRYPT_SI_ECURVE_XXX SYMCRYPT_SI_SCHEME_XXX3752// SYMCRYPT_SI_KAS_FFC SYMCRYPT_SI_SPG_XXX Hash Alg Id3753// SYMCRYPT_SI_KAS_FFC_SSC SYMCRYPT_SI_SPG_XXX SYMCRYPT_SI_SCHEME_XXX3754// SYMCRYPT_SI_LMS_SIGVER SYMCRYPT_LMS_XXX -3755// SYMCRYPT_SI_XMSS_SIGVER SYMCRYPT_XMSS_XXX -3756// SYMCRYPT_SI_XMSS_MT_SIGVER SYMCRYPT_XMSSMT_XXX -3757//3758//3759// Return value:3760// For the specified service and algorithm (and parameters if any), the function3761// returns 0 if SymCrypt implements the algorithm in an approved manner. A non-zero3762// value indicates either the algorithm is non-approved or the parameters were invalid.3763//3764// Remarks:3765// - For parameters that contain integer values, the callers must ensure that the values3766// are within the acceptable limits by using the SYMCRYPT_SI_CHECK_INT(L) macro.376737683769