//1// SymCrypt.h2//3// Copyright (c) Microsoft Corporation. Licensed under the MIT license.4//56#pragma once789#ifdef __cplusplus10extern "C" {11#endif1213#include "symcrypt_internal_shared.inc"1415#define SYMCRYPT_API_VERSION ((SYMCRYPT_CODE_VERSION_API << 16) | SYMCRYPT_CODE_VERSION_MINOR)1617//18// This is the header file for the SymCrypt library which contains19// implementations of cryptographic algorithms.20//21// All API information is in this file. Information in the22// other include files (symcrypt_internal.h) is subject23// to change at any time. Please use only the information in this file.24// The header file symcrypt_low_level contains low-level API functions that25// are sometimes needed. That API surface is not stable across releases.26//2728; // <-- non-functional semicolon that makes the editor's indent work properly.2930//31// General information about SymCrypt:32//33//34// CPU35// This library is built and tested for: X86, AMD64, ARM, and ARM64.36//37// ENVIRONMENT38// SymCrypt can run in different environments, such as kernel mode, user mode,39// etc.40// In earlier versions of the library, the caller specified the environment by passing a41// pointer to the SymCryptInit function.42// It turns out that that model no longer scales with the use of new extended register sets43// or it introduces too much overhead.44// The current library uses a different model. The user of the library invokes one of the45// environment macros inside a C file in the calling process.46// SymCrypt defines macros for each environment.47// The same mechanism will also be used to select between different implementations of a single48// algorithm. For example, a caller might use49// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE50// SYMCRYPT_SELECT_SHA256_COMPACT51// to indicate that the environment is kernel mode and the compact SHA-256 implementation is to52// be used.53// There are optimized environments for various Windows use cases.54//55//56// CHECKED BUILDS57// For each CPU, SymCrypt is available in both a checked build and a fre build. The58// checked build includes additional error checking which catches the most common59// errors. Please make sure you build a checked version of your binary and test with60// that regularly.61//62//63// MEMORY STRUCTURES64// Most SymCrypt functions do not allocate any memory; all memory is provided by the caller.65// However, callers may not copy, move, or otherwise manipulate the SymCrypt66// data structures. In particular, a memcpy of a SymCrypt data structure is not allowed.67// When necessary SymCrypt provides functions to perform the necessary manipulations.68// If you are missing one, please ask us.69//70//71// MULTI_THREADING72// The routines in this library are multi-thread safe, taking into account the usual73// rules of multiple threads accessing the same data structures.74// Any function that accepts a pointer-to-const argument must be assumed to read the75// corresponding data. If the function accepts a pointer-to-non-const it must be76// assumed to both read and write the data.77// It is safe for two threads to use the same data element as long as both of them78// are only reading from it. For example, an expanded key is typically passed as79// a pointer-to-const to the encryption and decryption routines. Thus, multiple80// threads can perform multiple encryptions/decryptions in parallel using the81// same expanded key.82//83// The normal memory re-order issues apply as well. If one thread initializes a84// data structure and the initialization function returns, it is NOT safe for85// another thread to read the data structure without a suitable memory barrier or86// synchronization primitive.87//88//89// SIDE CHANNELS90// Side channels are ways in which an attacker can receive information about what91// a target process is doing using other aspects than just the input/output behaviour92// of the target. For example, the memory subsystem, CPU load modulation, disk usage,93// and many other aspects can provide side-channels to an attacker.94//95// Wherever possible the implementations in SymCrypt have been hardened against side channels.96// The most important rules are that the instruction sequence and the memory addresses97// accessed do not depend on any of the data being processed.98// As a general rule, the actual data being processed is protected, but the99// length of the data (i.e. the number of bytes) is not protected in this way and100// is treated as public information.101//102// The implementation of the following algorithms are NOT side-channel safe:103// - non-AES-NI based AES104// used on CPUs that don't have AES-NI, or in kernel mode on x86 Win8 and below.105// - DES, 3DES, DESX106// - RC4107// Making these algorithms side-channel safe would incur an overhead that is too large.108//109//110// FATAL ERRORS111// This is a high-performance library with a minimum of error checking.112// Many functions do not return an error code; this avoids the cost of113// having any error checking on the caller's side for error situations that114// can never occur. However, this does assume that the caller is calling115// SymCrypt using a valid calling sequence with proper parameters.116// In some situations this library will detect improper parameters or117// calling sequences. In those situations the library will generate a fatal118// error, which leads to an abrupt termination of the process (bugcheck in119// kernel mode). Exceptional circumstances may also induce fatal errors within120// the library (i.e. a caller provided buffer causes an access violation when121// it is read, or the library is called without sufficient stack space for the122// requested operation).123// If a fatal error is generated within the library, the internal state of the124// library may be inconsistent (i.e. there may be outstanding memory allocations125// that will never be freed, or a lock may have been taken which will never be126// released). Callers should not catch fatal errors and continue executing, as127// there is no guarantee of stability.128// The checked version of the library has additional error checking which detects129// the most common errors. We strongly recommend that callers build and test a130// checked version of their binary to catch these common errors.131//132//133// ALGORITHM SELF TEST134// SymCrypt includes functions that perform simple self-tests on the algorithm135// implementations. These functions are designed to be used for FIPS certification136// of crypto binaries. They should never fail, and they generate a fatal error137// if they do fail.138// If you are not FIPS-certifying your binaries, you can ignore the self test functions.139//140//141// CHANGES FROM RSA32.LIB142// This library replaces the venerable rsa32(k).lib. The major changes are:143//144// - SymCrypt requires the caller to call a library initialization function145// before calling the various algorithm implementations.146// - SymCrypt requires the caller to specify the environment in which the library147// is running.148// - SymCrypt has a CHKed and FRE version for use in CHKed and FRE builds.149// - The API has been updated. The API is more consistent and has better support150// for 64-bit platforms (use of SIZE_T rather than UINT32 for lengths).151// - All algorithm implementations have been updated to reflect the152// latest cryptographic coding guidelines. Several security weaknesses153// in the RSA32.lib code have been fixed.154// - Code has been optimized for the newer CPUs.155// This includes support for AES-NI, PCLMULQDQ, AVX2, etc.156// Most algorithms are faster, especially the recommended algorithms.157// Some legacy algorithms are somewhat slower due to removal of assembler support.158// Note: performance on older CPUs, like the Pentium 4, is reduced in some places.159// - Code and data now go into their default segments.160// RSA32 has a kernel-mode version where the code and data go into161// special segments. This allows the crypto code to be made pageable or162// nonpageable separate from the rest of the executable. This feature is163// error-prone, and not widely used. Furthermore, it switches on a per-lib164// basis, rather than a per-functionality basis, which is the wrong granularity.165// - Added native support for HMAC-SHA256 and HMAC-SHA512.166// - Support for parallel hashing, improves throughput up to 500%.167// - SymCrypt does not support binary copying of internal state information, because168// it imposes restrictions on what the library can do.169// Thus, you may NOT do a memcpy or remote copy on any SymCrypt data structure.170// SymCrypt provides copy functions where necessary, if you need others please ask.171//172173//174// Error codes175//176// This is a high-performance library with a minimum of error checking. Most177// routines do not perform any error checking at all.178// Some routines perform internal consistency checks and will cause a fatal179// error if the library is used incorrectly.180//181// In a few cases routines return an error code when they are called incorrectly.182// Mostly this is for key expansion routines which return an error code when the key183// size is wrong. This allows a higher-level library to be agnostic as to the proper184// key sizes for an algorithm and use the SymCrypt library to detect key size errors.185//186// For performance reasons this library avoids per-message error codes wherever possible.187//188// As this library can be used in many different contexts---kernel mode, user mode,189// WinCE, Xbox, etc.---we don't use one of the standard error types but use our own.190// Callers should not depend on the integer value of any of these enums.191//192// Error codes will signal the cause of the error, but callers should not rely on the193// exact symbolic error code returned. Especially in situations where multiple errors194// occur at once (e.g. multiple invalid parameters) the exact error symbol returned195// could change between versions of the library.196//197198#ifndef _Return_type_success_199#define _Return_type_success_(expr)200#endif201202typedef _Return_type_success_( return == SYMCRYPT_NO_ERROR ) enum {203SYMCRYPT_NO_ERROR = 0,204SYMCRYPT_UNUSED = 0x8000, // Start our error codes here so they're easier to distinguish205SYMCRYPT_WRONG_KEY_SIZE,206SYMCRYPT_WRONG_BLOCK_SIZE,207SYMCRYPT_WRONG_DATA_SIZE,208SYMCRYPT_WRONG_NONCE_SIZE,209SYMCRYPT_WRONG_TAG_SIZE,210SYMCRYPT_WRONG_ITERATION_COUNT,211SYMCRYPT_AUTHENTICATION_FAILURE,212SYMCRYPT_EXTERNAL_FAILURE,213SYMCRYPT_FIPS_FAILURE,214SYMCRYPT_HARDWARE_FAILURE,215SYMCRYPT_NOT_IMPLEMENTED,216SYMCRYPT_INVALID_BLOB,217SYMCRYPT_BUFFER_TOO_SMALL,218SYMCRYPT_INVALID_ARGUMENT,219SYMCRYPT_MEMORY_ALLOCATION_FAILURE,220SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE,221SYMCRYPT_INCOMPATIBLE_FORMAT,222SYMCRYPT_VALUE_TOO_LARGE,223SYMCRYPT_SESSION_REPLAY_FAILURE,224SYMCRYPT_HBS_NO_OTS_KEYS_LEFT,225SYMCRYPT_HBS_PUBLIC_ROOT_MISMATCH,226} SYMCRYPT_ERROR;227228// SYMCRYPT_ECURVE_TYPE needs to be completely defined before including229// symcrypt_internal.h because it's a member of another type in there.230typedef enum _SYMCRYPT_ECURVE_TYPE {231SYMCRYPT_ECURVE_TYPE_NULL = 0,232SYMCRYPT_ECURVE_TYPE_SHORT_WEIERSTRASS = 1,233SYMCRYPT_ECURVE_TYPE_TWISTED_EDWARDS = 2,234SYMCRYPT_ECURVE_TYPE_MONTGOMERY = 3,235} SYMCRYPT_ECURVE_TYPE;236//237// SYMCRYPT_ECURVE_TYPE is used to specify the type of the curve.238//239240// SYMCRYPT_DLGROUP_FIPS needs to be completely defined before including241// symcrypt_internal.h because it's a member of another type in there.242243//=====================================================244// DL group operations245246typedef enum _SYMCRYPT_DLGROUP_FIPS {247SYMCRYPT_DLGROUP_FIPS_NONE = 0,248SYMCRYPT_DLGROUP_FIPS_186_2 = 1,249SYMCRYPT_DLGROUP_FIPS_186_3 = 2,250} SYMCRYPT_DLGROUP_FIPS;251//252// Dlgroup enums for the generation and verification of the group parameters.253// These are used in:254// - SymCryptDlgroupGenerate function to specify the appropriate standard to255// be used.256// - SymCryptDlgroupSetValue function to verify that the input parameters were257// properly generated.258//259260typedef enum _SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE {261SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE_NONE = 0,262SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE_IKE_3526 = 1,263SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE_TLS_7919 = 2,264} SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE;265#define SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE_DEFAULT SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE_TLS_7919266//267// Dlgroup enums for the specification and verification of the named safe prime group parameters.268// These are used in:269// - SymCryptDlgroupGenerateSafePrime function to specify the appropriate group to270// be used.271//272273//274// The symcrypt_internal.h file contains information only relevant to the internals275// of the library, but they have to be exposed to the compiler of the caller.276// We put those in a separate file to make this file easier to read277// for users of the library.278// The details in the symcrypt_internal.h file can change at any time;279// users should only rely on the information in this header file.280//281#include "symcrypt_internal.h"282283//284// Useful macros285//286// A variety of useful macros.287//288// The load/store macros convert from integer types to an array of bytes and vice versa.289// LOAD<n>_* (p) loads a value of <n> bits from the byte pointer p.290// STORE<n>_* (p,v) stores the n-bit value v to byte pointer p.291// The macros can either do Most Significant Byte first (big-endian) or292// Least Significant Byte first.293// The actual definitions are in the symcrypt_internal.h file because they contain294// items that are not part of the stable public API of SymCrypt.295//296297#define SYMCRYPT_LOAD_LSBFIRST16( p ) SYMCRYPT_INTERNAL_LOAD_LSBFIRST16( p )298#define SYMCRYPT_LOAD_LSBFIRST32( p ) SYMCRYPT_INTERNAL_LOAD_LSBFIRST32( p )299#define SYMCRYPT_LOAD_LSBFIRST64( p ) SYMCRYPT_INTERNAL_LOAD_LSBFIRST64( p )300301#define SYMCRYPT_LOAD_MSBFIRST16( p ) SYMCRYPT_INTERNAL_LOAD_MSBFIRST16( p )302#define SYMCRYPT_LOAD_MSBFIRST32( p ) SYMCRYPT_INTERNAL_LOAD_MSBFIRST32( p )303#define SYMCRYPT_LOAD_MSBFIRST64( p ) SYMCRYPT_INTERNAL_LOAD_MSBFIRST64( p )304305#define SYMCRYPT_STORE_LSBFIRST16( p, v ) SYMCRYPT_INTERNAL_STORE_LSBFIRST16( p, v )306#define SYMCRYPT_STORE_LSBFIRST32( p, v ) SYMCRYPT_INTERNAL_STORE_LSBFIRST32( p, v )307#define SYMCRYPT_STORE_LSBFIRST64( p, v ) SYMCRYPT_INTERNAL_STORE_LSBFIRST64( p, v )308309#define SYMCRYPT_STORE_MSBFIRST16( p, v ) SYMCRYPT_INTERNAL_STORE_MSBFIRST16( p, v )310#define SYMCRYPT_STORE_MSBFIRST32( p, v ) SYMCRYPT_INTERNAL_STORE_MSBFIRST32( p, v )311#define SYMCRYPT_STORE_MSBFIRST64( p, v ) SYMCRYPT_INTERNAL_STORE_MSBFIRST64( p, v )312313//314// Convert between UINT32/UINT64 and variable-sized byte buffers315//316// The load functions take any size input array, and will return an error if the value317// encoded in the array exceeds the range of the target type (UINT32 or UINT64).318// The store functions will return an error if the destination buffer is too small319// to encode the actual value passed.320// An empty buffer (length = 0) encodes the value 0, and the value 0 can be encoded321// in the empty buffer.322// These functions are not side-channel safe.323//324325SYMCRYPT_ERROR326SYMCRYPT_CALL327SymCryptLoadLsbFirstUint32(328_In_reads_( cbSrc ) PCBYTE pbSrc,329SIZE_T cbSrc,330_Out_ PUINT32 pDst );331332SYMCRYPT_ERROR333SYMCRYPT_CALL334SymCryptLoadLsbFirstUint64(335_In_reads_( cbSrc ) PCBYTE pbSrc,336SIZE_T cbSrc,337_Out_ PUINT64 pDst );338339SYMCRYPT_ERROR340SYMCRYPT_CALL341SymCryptLoadMsbFirstUint32(342_In_reads_( cbSrc ) PCBYTE pbSrc,343SIZE_T cbSrc,344_Out_ PUINT32 pDst );345346SYMCRYPT_ERROR347SYMCRYPT_CALL348SymCryptLoadMsbFirstUint64(349_In_reads_( cbSrc ) PCBYTE pbSrc,350SIZE_T cbSrc,351_Out_ PUINT64 pDst );352353SYMCRYPT_ERROR354SYMCRYPT_CALL355SymCryptStoreLsbFirstUint32(356UINT32 src,357_Out_writes_( cbDst ) PBYTE pbDst,358SIZE_T cbDst );359360SYMCRYPT_ERROR361SYMCRYPT_CALL362SymCryptStoreLsbFirstUint64(363UINT64 src,364_Out_writes_( cbDst ) PBYTE pbDst,365SIZE_T cbDst );366367SYMCRYPT_ERROR368SYMCRYPT_CALL369SymCryptStoreMsbFirstUint32(370UINT32 src,371_Out_writes_( cbDst ) PBYTE pbDst,372SIZE_T cbDst );373374SYMCRYPT_ERROR375SYMCRYPT_CALL376SymCryptStoreMsbFirstUint64(377UINT64 src,378_Out_writes_( cbDst ) PBYTE pbDst,379SIZE_T cbDst );380381//382// Functions to retrieve the bitsize/bytesize of UINT32/UINT64 values383// Note: the bitsize/bytesize of the value 0 is defined as 0.384// Some data formats don't allow empty encodings, so the caller385// should ensure they handle the 0-case properly.386// These functions are NOT side-channel safe.387//388UINT32389SymCryptUint32Bitsize( UINT32 value );390391UINT32392SymCryptUint64Bitsize( UINT64 value );393394UINT32395SymCryptUint32Bytesize( UINT32 value );396397UINT32398SymCryptUint64Bytesize( UINT64 value );399400401//402// FORCED MEMORY ACCESS403//404// These macros force a memory access. That is, they require that the memory405// read or write takes place, and do not allow the compiler to optimize the access406// away. This is useful for wiping memory even if the compiler knows the memory will not be used in future.407//408// The READ<n> macros read an n-bit value from a PBYTE and return a BYTE if n=8 and an UINT<n> otherwise.409// The WRITE<n> macros write a value to a PBYTE using the same types as the corresponding READ<n>410//411// These macros provide no other memory ordering requirements, so there are no acquire/release412// semantics, memory barriers, etc.413//414415#define SYMCRYPT_FORCE_READ8( _p ) SYMCRYPT_INTERNAL_FORCE_READ8( _p )416#define SYMCRYPT_FORCE_READ16( _p ) SYMCRYPT_INTERNAL_FORCE_READ16( _p )417#define SYMCRYPT_FORCE_READ32( _p ) SYMCRYPT_INTERNAL_FORCE_READ32( _p )418#define SYMCRYPT_FORCE_READ64( _p ) SYMCRYPT_INTERNAL_FORCE_READ64( _p )419420#define SYMCRYPT_FORCE_WRITE8( _p, _v ) SYMCRYPT_INTERNAL_FORCE_WRITE8( _p, _v )421#define SYMCRYPT_FORCE_WRITE16( _p, _v ) SYMCRYPT_INTERNAL_FORCE_WRITE16( _p, _v )422#define SYMCRYPT_FORCE_WRITE32( _p, _v ) SYMCRYPT_INTERNAL_FORCE_WRITE32( _p, _v )423#define SYMCRYPT_FORCE_WRITE64( _p, _v ) SYMCRYPT_INTERNAL_FORCE_WRITE64( _p, _v )424425//==========================================================================426// TYPE MODIFIERS427//==========================================================================428//429// The SymCrypt library uses the following type modifiers430//431// SYMCRYPT_CALL432//433// The calling-convention used by SymCrypt functions.434// Some platforms have multiple calling conventions which differ in the435// way arguments are passed and the stack is handled436// The SYMCRYPT_CALL type modifier selects the correct calling convention.437// The current implementation uses __fastcall on the x86 platform, which438// passes arguments in registers and is generally faster than the __stdcall439// calling convention.440//441//442// SYMCRYPT_ALIGN443//444// On platforms that support alignment declaration this macro expands to445// __declspec(align(<n>)) where <n> is platform-dependent.446// Many data types that SymCrypt defines are SYMCRYPT_ALIGNed.447// When allocating memory for any SymCrypt data type the caller448// has to ensure that the memory is aligned to the natural alignment for449// that platform. (e.g. 4 for x86, 16 for x64)450// Memory allocation functions typically return properly aligned memory blocks.451// The macro SYMCRYPT_ALIGN_VALUE contains the actual value of <n>.452//453454//==========================================================================455// LIBRARY MANAGEMENT456//==========================================================================457//458// SymCrypt runs in many different environments. Boot library, kernel, user mode,459// (for each of x86, amd64, arm), and possibly WinCE, Mobile, Zune, Xbox, etc.460// These different environments can have different requirements.461//462// Creating different libraries for each environment has huge testing and maintenance463// costs. Instead, the user of the library invokes a pre-defined macro in their own code464// that contains the necessary adoptions to that environment.465// Using a macro makes the selection static, which allows the compiler to optimize466// away a lot of the overhead.467// (e.g. if XMM register saving is not needed, the stub function declared by the macro468// will always succeed, and the compiler will inline it and optimize it away.)469//470// Warning: due to recent changes in the Visual Studio C runtime, we cannot test saving471// of the YMM registers in Windows user mode. Because we do not have a kernel mode test472// for saving/restoring the YMM registers, this functionality is currently not tested.473// Before using SymCrypt in Windows 7 kernel mode, additional kernel mode tests should be474// added to verify this functionality.475//476477//478// The following environment macros are available. Callers should invoke one of these479// in their own code.480//481// SYMCRYPT_ENVIRONMENT_WINDOWS_BOOTLIBRARY // only for the current OS release482//483// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_LEGACY // Use for any version of Windows.484// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_WIN7_N_LATER // Only for Win7 and later485// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_WIN8_1_N_LATER // Only for WinBlue and later486// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELMODE_LATEST // use for latest OS487//488// SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_LEGACY // use for any version of Windows489// SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN7_N_LATER // Only for Win7 and later (cannot use AVX2 instructions)490// SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_WIN8_1_N_LATER // Only for Win8.1 and later491// SYMCRYPT_ENVIRONMENT_WINDOWS_USERMODE_LATEST // use for latest OS492//493// SYMCRYPT_ENVIRONMENT_WINDOWS_KERNELDEBUGGER494//495// SYMCRYPT_ENVIRONMENT_LINUX_USERMODE // use for Linux496//497// SYMCRYPT_ENVIRONMENT_OPTEE_TA // use for OPTEE498//499// SYMCRYPT_ENVIRONMENT_GENERIC // use for all other situations500//501502VOID503SYMCRYPT_CALL504SymCryptInit(void);505//506// Initialize the static library.507// This function MUST be called before any other function in the library.508// It is not necessary to call this function when using the shared object library.509//510// This function does not perform the self tests in the library.511// Doing so would force the linking of all the algorithm in the library,512// which is obviously not desirable for applications that want to link in513// only one or two algorithms.514// If self test are required (e.g. for FIPS certification) they have to be515// called separately for each algorithm.516//517// It is safe to call this function multiple times.518// The library initialization is done in the first call; subsequent calls are no-ops.519//520// If you get an 'undefined symbol' error on this function name, then you forgot521// to invoke one of the environment macros documented above.522//523524VOID525SYMCRYPT_CALL526SymCryptModuleInit(527_In_ UINT32 api,528_In_ UINT32 minor);529530#define SYMCRYPT_MODULE_INIT() SymCryptModuleInit( SYMCRYPT_CODE_VERSION_API, SYMCRYPT_CODE_VERSION_MINOR );531//532// Initialize the SymCrypt shared object module/dynamic-link library. This function verifies533// that the module version supports the version requested by the application. If the version534// is unsupported, a fatal error will occur. Rather than explicitly calling SymCryptModuleInit,535// the macro SYMCRYPT_MODULE_INIT should be used to call it with the correct arguments.536//537538//==========================================================================539// DATA MANIPULATION540//==========================================================================541//542// This library provides some data manipulation functions that commonly occur543// in cryptographic code.544//545546VOID547SYMCRYPT_CALL548SymCryptWipe(549_Out_writes_bytes_( cbData ) PVOID pbData,550SIZE_T cbData );551552FORCEINLINE553VOID554SYMCRYPT_CALL555SymCryptWipeKnownSize(556_Out_writes_bytes_( cbData ) PVOID pbData,557SIZE_T cbData );558559//560// The SymCryptWipe and SymCryptWipeKnownSize functions wipe memory.561// They work for any size and any alignment.562// Wiping is faster on x86 and x64 if the data buffer is 16-aligned,563// and the size is a multiple of 16.564//565// The SymCryptWipe function is optimized for the case where the size of the buffer566// is not known at compile time.567//568// The SymCryptWipeKnownSize function is optimized for the case where the569// cbData parameter is a compile-time known value.570//571// The two functions are functionally equivalent, but there can be a significant performance572// differences:573// - calling SymCryptWipeKnownSize when the size is not known at compile time incurs a574// code size penalty.575// - calling SymCryptWipeKnownSize when the size is not known at compile time and is sometimes <= 64576// incurs a performance penalty.577// (The code assumes that the compiler can optimize all the conditional jumps away.578// Conditional jumps can be very expensive if they are not predicted correctly.)579// - calling SymCryptWipe when the buffer is small and has a compile-time known size incurs580// a performance penalty.581// When in doubt, use SymCryptWipe.582//583584VOID585SYMCRYPT_CALL586SymCryptXorBytes(587_In_reads_( cbBytes ) PCBYTE pbSrc1,588_In_reads_( cbBytes ) PCBYTE pbSrc2,589_Out_writes_( cbBytes ) PBYTE pbResult,590SIZE_T cbBytes );591//592// Xor two strings of bytes together.593//594// The result buffer can be the same as Src1 or Src2, or can be non-overlapping595// with the inputs. However, the result buffer may not partially overlap with596// one of the inputs.597//598599BOOLEAN600SYMCRYPT_CALL601SymCryptEqual(602_In_reads_( cbBytes ) PCBYTE pbSrc1,603_In_reads_( cbBytes ) PCBYTE pbSrc2,604SIZE_T cbBytes );605//606// Compare two regions of memory and return TRUE if they are equal, FALSE otherwise.607//608// This function compares all the bytes without an early-out mechanism.609// An early-out implementation, such as memcmp, reveals through side channels610// the position of the first byte where the inputs differ, which leaks information.611//612613614//==========================================================================615// HASH FUNCTIONS616//==========================================================================617//618// All hash functions have a similar interface. For consistency we describe619// the generic parts of the interface once.620// Algorithm-specific comments are given with the API functions of each algorithm separately.621//622// For an algorithm called XXX the following functions, types, and constants are defined:623//624//625// SYMCRYPT_XXX_RESULT_SIZE626//627// A constant giving the size, in bytes, of the result of the hash function.628//629//630// SYMCRYPT_XXX_INPUT_BLOCK_SIZE631//632// A constant giving the natural input block size for the hash function.633// Most callers don't need to know this, but some uses, like the HMAC construction634// adapt to this size to improve efficiency.635//636//637// VOID638// SYMCRYPT_CALL639// SymCryptXxx( _In_reads_( cbData ) PCBYTE pbData,640// SIZE_T cbData,641// _Out_writes_( SYMCRYPT_XXX_RESULT_SIZE ) PBYTE pbResult );642//643// Computes the hash value of the data buffer.644// If you have all the data to be hashed in a single buffer this is the simplest function to use.645//646//647// SYMCRYPT_XXX_STATE648//649// Type to store the intermediate state of a hash computation.650// This is an opaque type whose structure can change at will.651// It should only be used for transient computations in a single executable652// and not be stored or transferred to a different process.653// The pointer version is also defined (PSYMCRYPT_XXX_STATE)654//655// The SYMCRYPT_XXX_STATE structure contains the entire state of an ongoing656// hash computation. If you want to compute the hash on several strings that657// have the same prefix, the caller may hash the prefix first, then create658// multiple copies using the supplied state copy function,659// and continue hashing the different states with different postfix strings.660//661// VOID662// SYMCRYPT_CALL663// SymCryptXxxInit( _Out_ PSYMCRYPT_XXX_STATE pState );664//665// Initialize a SYMCRYPT_XXX_STATE for subsequent use.666//667// The state encodes an ongoing hash computation and allows incremental668// computation of a hash function.669// At any point in time the state object encodes a state that is equivalent to670// the hash computation of a data string.671// This function can be called at any time and resets the state to correspond672// to the empty data string.673// The SymCryptXxxAppend function appends data to the data string674// encoded by the state.675// The SymCryptXxxResult function finalizes the computation and676// returns the actual hash result.677//678//679// VOID680// SYMCRYPT_CALL681// SymCryptXxxAppend( _Inout_ PSYMCRYPT_XXX_STATE pState,682// _In_reads_( cbData ) PCBYTE pbData,683// SIZE_T cbData );684//685// Provide more data to the ongoing hash computation specified by the state.686// The state must have been initialized by SymCryptXxxInit.687// This function can be called multiple times on the same state688// to append more data to the encoded data string.689//690//691// VOID692// SYMCRYPT_CALL693// SymCryptXxxResult(694// _Inout_ PSYMCRYPT_XXX_STATE pState,695// _Out_writes_( SYMCRYPT_XXX_RESULT_SIZE )PBYTE pbResult );696//697// Returns the hash of the data string encoded by the state.698// If the state was newly initialized this returns the hash of the empty string.699// If one or more SymCryptXxxAppend function calls were made on this state700// it returns the hash of the concatenation of all the data strings701// passed to SymCryptXxxAppend.702//703// The state is re-initialized and ready for re-use; you do not have to call704// SymCryptXxxInit on the state to start another fresh hash computation.705// The state is also wiped of any traces of old data to prevent accidental data leakage.706//707//708// VOID709// SYMCRYPT_CALL710// SymCryptXxxStateCopy( _In_ PCSYMCRYPT_XXX_STATE pSrc, _Out_ PSYMCRYPT_XXX_STATE pDst );711//712// Create a new copy of the state object.713//714//715// VOID716// SYMCRYPT_CALL717// SymCryptXxxStateExport(718// _In_ PCSYMCRYPT_XXX_STATE pState,719// _Out_writes_bytes_( SYMCRYPT_XXX_STATE_EXPORT_SIZE ) PBYTE pbBlob );720//721// Converts a hash state to an exported format that can be persisted and re-imported.722// The exported blob is compatible across CPU architectures, and across different723// versions of SymCrypt.724//725// pState must point to a valid initialized hash state.726//727//728// SYMCRYPT_ERROR729// SYMCRYPT_CALL730// SymCryptXxxStateImport(731// _Out_ PSYMCRYPT_XXX_STATE pState,732// _In_reads_bytes_( SYMCRYPT_XXX_STATE_EXPORT_SIZE) PCBYTE pbBlob );733//734// Imports a hash state that was previously exported with SymCryptXxxStateExport.735// After this call, the effective state of *pState is identical to the effective736// state of *pState that was passed to the SymCryptXxxStateExport function which737// created this blob.738//739// This function returns an error if the blob is incorrectly formatted.740//741//742// VOID743// SYMCRYPT_CALL744// SymCryptXxxSelftest(void);745//746// Perform a minimal self-test on the XXX algorithm.747// This function is designed to be used for achieving FIPS 140-2 compliance or748// to provide a simple self-test when an application starts.749//750// If an error is detected, a platform-specific fatal error action is taken.751// Callers do not need to handle any error conditions.752//753//754//755//756// There are also generic Hash functions that use a virtual table and work757// for any hash algorithm.758// Virtual table addresses that callers can use are supplied through a const-ptr-const definition.759// This supports an application switching the underlying implementation of one algorithm760// without the need to re-compile all the intermediate libraries in between.761// For example, you could use the same signature verification library with the fast hash implementation in one binary,762// and with a compact hash implementation in a second binary, without needing a different763// signature verification library.764//765766typedef enum _SYMCRYPT_HASH_ID767{768SYMCRYPT_HASH_ID_NULL = 0,769SYMCRYPT_HASH_ID_MD2 = 1,770SYMCRYPT_HASH_ID_MD4 = 2,771SYMCRYPT_HASH_ID_MD5 = 3,772SYMCRYPT_HASH_ID_SHA1 = 4,773SYMCRYPT_HASH_ID_SHA224 = 5,774SYMCRYPT_HASH_ID_SHA256 = 6,775SYMCRYPT_HASH_ID_SHA384 = 7,776SYMCRYPT_HASH_ID_SHA512 = 8,777SYMCRYPT_HASH_ID_SHA512_224 = 9,778SYMCRYPT_HASH_ID_SHA512_256 = 10,779SYMCRYPT_HASH_ID_SHA3_224 = 11,780SYMCRYPT_HASH_ID_SHA3_256 = 12,781SYMCRYPT_HASH_ID_SHA3_384 = 13,782SYMCRYPT_HASH_ID_SHA3_512 = 14,783SYMCRYPT_HASH_ID_SHAKE128 = 15,784SYMCRYPT_HASH_ID_SHAKE256 = 16785} SYMCRYPT_HASH_ID;786787PCSYMCRYPT_HASH788SYMCRYPT_CALL789SymCryptGetHashAlgorithm( SYMCRYPT_HASH_ID hashId );790//791// Returns a pointer to the hash algorithm structure for the specified hash ID.792// Returns NULL if the hash ID is invalid.793//794795SIZE_T796SYMCRYPT_CALL797SymCryptHashResultSize( _In_ PCSYMCRYPT_HASH pHash );798799SIZE_T800SYMCRYPT_CALL801SymCryptHashInputBlockSize( _In_ PCSYMCRYPT_HASH pHash );802803SIZE_T804SYMCRYPT_CALL805SymCryptHashStateSize( _In_ PCSYMCRYPT_HASH pHash );806//807// SymCryptHashStateSize808//809// Returns the size, in bytes, of the hash state for this hash algorithm.810// Note that the state must be SYMCRYPT_ALIGNed.811// Alternatively, the SYMCRYPT_HASH_STATE structure is large enough to contain812// any Symcrypt-implemented hash state, so sizeof( SYMCRYPT_HASH_STATE ) is always813// large enough to contain a hash state.814//815816VOID817SYMCRYPT_CALL818SymCryptHash(819_In_ PCSYMCRYPT_HASH pHash,820_In_reads_( cbData ) PCBYTE pbData,821SIZE_T cbData,822_Out_writes_( SYMCRYPT_MIN( cbResult, pHash->resultSize ) ) PBYTE pbResult,823SIZE_T cbResult );824//825// SymCryptHash826//827// Compute a hash value using any hash function.828// The number of bytes written to the pbResult buffer is829// min( cbResult, SymCryptHashResultSize( pHash ) )830//831832VOID833SYMCRYPT_CALL834SymCryptHashInit(835_In_ PCSYMCRYPT_HASH pHash,836_Out_writes_bytes_( pHash->stateSize ) PVOID pState );837838VOID839SYMCRYPT_CALL840SymCryptHashAppend(841_In_ PCSYMCRYPT_HASH pHash,842_Inout_updates_bytes_( pHash->stateSize ) PVOID pState,843_In_reads_( cbData ) PCBYTE pbData,844SIZE_T cbData );845846VOID847SYMCRYPT_CALL848SymCryptHashResult(849_In_ PCSYMCRYPT_HASH pHash,850_Inout_updates_bytes_( pHash->stateSize ) PVOID pState,851_Out_writes_( SYMCRYPT_MIN( cbResult, pHash->resultSize ) ) PBYTE pbResult,852SIZE_T cbResult );853//854// SymCryptHashResult855//856// Finalizes the hash computation by calling the resultFunc member857// of pHash.858// The hash result is produced to an internal buffer and859// the number of bytes written to the pbResult buffer is860// min( cbResult, SymCryptHashResultSize( pHash ) )861862VOID863SYMCRYPT_CALL864SymCryptHashStateCopy(865_In_ PCSYMCRYPT_HASH pHash,866_In_reads_(pHash->stateSize) PCVOID pSrc,867_Out_writes_(pHash->stateSize) PVOID pDst);868//869// SymCryptHashStateCopy870//871// Copies the hash state from pSrc to pDst.872873////////////////////////////////////////////////////////////////////////////874// MD2875//876// Tha MD2 hash algorithm per RFC1319.877//878// The MD2 hash function has not received widespread analysis and is very slow879// compared to contemporary algorithms.880//881// The SymCrypt implementation of MD2 uses table lookups which leads to a side-channel882// vulnerability.883//884// Per the Crypto SDL, any use of this algorithm in Microsoft code requires885// a Crypto board exemption. Whenever possible, please use SHA-256 or SHA-512.886//887// For details on this API see the description above about the generic hash function API.888//889890#define SYMCRYPT_MD2_RESULT_SIZE (16)891#define SYMCRYPT_MD2_INPUT_BLOCK_SIZE (16)892893VOID894SYMCRYPT_CALL895SymCryptMd2(896_In_reads_( cbData ) PCBYTE pbData,897SIZE_T cbData,898_Out_writes_( SYMCRYPT_MD2_RESULT_SIZE ) PBYTE pbResult );899900VOID901SYMCRYPT_CALL902SymCryptMd2Init( _Out_ PSYMCRYPT_MD2_STATE pState );903904VOID905SYMCRYPT_CALL906SymCryptMd2Append(907_Inout_ PSYMCRYPT_MD2_STATE pState,908_In_reads_( cbData ) PCBYTE pbData,909SIZE_T cbData );910911VOID912SYMCRYPT_CALL913SymCryptMd2Result(914_Inout_ PSYMCRYPT_MD2_STATE pState,915_Out_writes_( SYMCRYPT_MD2_RESULT_SIZE ) PBYTE pbResult );916917VOID918SYMCRYPT_CALL919SymCryptMd2StateCopy( _In_ PCSYMCRYPT_MD2_STATE pSrc, _Out_ PSYMCRYPT_MD2_STATE pDst );920921VOID922SYMCRYPT_CALL923SymCryptMd2StateExport(924_In_ PCSYMCRYPT_MD2_STATE pState,925_Out_writes_bytes_( SYMCRYPT_MD2_STATE_EXPORT_SIZE ) PBYTE pbBlob );926927SYMCRYPT_ERROR928SYMCRYPT_CALL929SymCryptMd2StateImport(930_Out_ PSYMCRYPT_MD2_STATE pState,931_In_reads_bytes_( SYMCRYPT_MD2_STATE_EXPORT_SIZE) PCBYTE pbBlob );932933VOID934SYMCRYPT_CALL935SymCryptMd2Selftest(void);936937extern const PCSYMCRYPT_HASH SymCryptMd2Algorithm;938939////////////////////////////////////////////////////////////////////////////940// MD4941//942// Tha MD4 hash algorithm per RFC1320.943// This implementation is limited to data strings that are in whole bytes.944// Odd bit length are not supported.945//946// The MD4 hash function has been badly broken and is not considered secure.947// Per the Crypto SDL, any use of this algorithm in Microsoft code requires948// a Crypto board exemption. Whenever possible, please use SHA-256 or SHA-512.949//950// For details on this API see the description above about the generic hash function API.951//952953#define SYMCRYPT_MD4_RESULT_SIZE (16)954#define SYMCRYPT_MD4_INPUT_BLOCK_SIZE (64)955956VOID957SYMCRYPT_CALL958SymCryptMd4(959_In_reads_( cbData ) PCBYTE pbData,960SIZE_T cbData,961_Out_writes_( SYMCRYPT_MD4_RESULT_SIZE ) PBYTE pbResult );962963VOID964SYMCRYPT_CALL965SymCryptMd4Init( _Out_ PSYMCRYPT_MD4_STATE pState );966967VOID968SYMCRYPT_CALL969SymCryptMd4Append(970_Inout_ PSYMCRYPT_MD4_STATE pState,971_In_reads_( cbData ) PCBYTE pbData,972SIZE_T cbData );973974VOID975SYMCRYPT_CALL976SymCryptMd4Result(977_Inout_ PSYMCRYPT_MD4_STATE pState,978_Out_writes_( SYMCRYPT_MD4_RESULT_SIZE ) PBYTE pbResult );979980VOID981SYMCRYPT_CALL982SymCryptMd4StateCopy( _In_ PCSYMCRYPT_MD4_STATE pSrc, _Out_ PSYMCRYPT_MD4_STATE pDst );983984VOID985SYMCRYPT_CALL986SymCryptMd4StateExport(987_In_ PCSYMCRYPT_MD4_STATE pState,988_Out_writes_bytes_( SYMCRYPT_MD4_STATE_EXPORT_SIZE ) PBYTE pbBlob );989990SYMCRYPT_ERROR991SYMCRYPT_CALL992SymCryptMd4StateImport(993_Out_ PSYMCRYPT_MD4_STATE pState,994_In_reads_bytes_( SYMCRYPT_MD4_STATE_EXPORT_SIZE) PCBYTE pbBlob );995996VOID997SYMCRYPT_CALL998SymCryptMd4Selftest(void);9991000extern const PCSYMCRYPT_HASH SymCryptMd4Algorithm;10011002////////////////////////////////////////////////////////////////////////////1003// MD51004//1005// Tha MD5 hash algorithm per RFC1321.1006// This implementation is limited to data strings that are in whole bytes.1007// Odd bit length are not supported.1008//1009// The MD5 hash function has been badly broken and is not considered secure.1010// Per the Crypto SDL, any use of this algorithm in Microsoft code requires1011// a Crypto board exemption. Whenever possible, please use SHA-256 or SHA-512.1012//1013// For details on this API see the description above about the generic hash function API.1014//10151016#define SYMCRYPT_MD5_RESULT_SIZE (16)1017#define SYMCRYPT_MD5_INPUT_BLOCK_SIZE (64)10181019VOID1020SYMCRYPT_CALL1021SymCryptMd5(1022_In_reads_( cbData ) PCBYTE pbData,1023SIZE_T cbData,1024_Out_writes_( SYMCRYPT_MD5_RESULT_SIZE ) PBYTE pbResult );10251026VOID1027SYMCRYPT_CALL1028SymCryptMd5Init( _Out_ PSYMCRYPT_MD5_STATE pState );10291030VOID1031SYMCRYPT_CALL1032SymCryptMd5Append(1033_Inout_ PSYMCRYPT_MD5_STATE pState,1034_In_reads_( cbData ) PCBYTE pbData,1035SIZE_T cbData );10361037VOID1038SYMCRYPT_CALL1039SymCryptMd5Result(1040_Inout_ PSYMCRYPT_MD5_STATE pState,1041_Out_writes_( SYMCRYPT_MD5_RESULT_SIZE ) PBYTE pbResult );10421043VOID1044SYMCRYPT_CALL1045SymCryptMd5StateCopy( _In_ PCSYMCRYPT_MD5_STATE pSrc, _Out_ PSYMCRYPT_MD5_STATE pDst );10461047VOID1048SYMCRYPT_CALL1049SymCryptMd5StateExport(1050_In_ PCSYMCRYPT_MD5_STATE pState,1051_Out_writes_bytes_( SYMCRYPT_MD5_STATE_EXPORT_SIZE ) PBYTE pbBlob );10521053SYMCRYPT_ERROR1054SYMCRYPT_CALL1055SymCryptMd5StateImport(1056_Out_ PSYMCRYPT_MD5_STATE pState,1057_In_reads_bytes_( SYMCRYPT_MD5_STATE_EXPORT_SIZE) PCBYTE pbBlob );10581059VOID1060SYMCRYPT_CALL1061SymCryptMd5Selftest(void);10621063extern const PCSYMCRYPT_HASH SymCryptMd5Algorithm;106410651066///////////////////////////////////////////////////////////////////////////////1067// SHA-11068//1069// The SHA-1 hash algorithm per FIPS 180-4.1070//1071// This implementation is limited to data strings that are in whole bytes.1072// Odd bit length are not supported.1073//1074// The SHA-1 standard limits data inputs to a maximum of 2^61-1 bytes.1075// This implementation supports larger inputs, and simply wraps the internal message1076// length counter. Note that the security properties are unknown for1077// such long messages, and their use is not recommended.1078//1079// The SHA-1 hash algorithm has been broken in a technical sense, and future1080// attacks can only get better.1081// This algorithm is not recommended for new applications and should only be used1082// for backward compatibility.1083// Per the Crypto SDL, new uses of this algorithm in Microsoft code require1084// a Crypto board exemption. Whenever possible, please use SHA-256 or SHA-512.1085//1086// For details on this API see the description above about the generic hash function API.1087//10881089#define SYMCRYPT_SHA1_RESULT_SIZE (20)1090#define SYMCRYPT_SHA1_INPUT_BLOCK_SIZE (64)10911092VOID1093SYMCRYPT_CALL1094SymCryptSha1(1095_In_reads_( cbData ) PCBYTE pbData,1096SIZE_T cbData,1097_Out_writes_( SYMCRYPT_SHA1_RESULT_SIZE ) PBYTE pbResult );10981099VOID1100SYMCRYPT_CALL1101SymCryptSha1Init( _Out_ PSYMCRYPT_SHA1_STATE pState );11021103VOID1104SYMCRYPT_CALL1105SymCryptSha1Append(1106_Inout_ PSYMCRYPT_SHA1_STATE pState,1107_In_reads_( cbData ) PCBYTE pbData,1108SIZE_T cbData );11091110VOID1111SYMCRYPT_CALL1112SymCryptSha1Result(1113_Inout_ PSYMCRYPT_SHA1_STATE pState,1114_Out_writes_( SYMCRYPT_SHA1_RESULT_SIZE )PBYTE pbResult );11151116VOID1117SYMCRYPT_CALL1118SymCryptSha1StateCopy( _In_ PCSYMCRYPT_SHA1_STATE pSrc, _Out_ PSYMCRYPT_SHA1_STATE pDst );11191120VOID1121SYMCRYPT_CALL1122SymCryptSha1StateExport(1123_In_ PCSYMCRYPT_SHA1_STATE pState,1124_Out_writes_bytes_( SYMCRYPT_SHA1_STATE_EXPORT_SIZE ) PBYTE pbBlob );11251126SYMCRYPT_ERROR1127SYMCRYPT_CALL1128SymCryptSha1StateImport(1129_Out_ PSYMCRYPT_SHA1_STATE pState,1130_In_reads_bytes_( SYMCRYPT_SHA1_STATE_EXPORT_SIZE) PCBYTE pbBlob );11311132VOID1133SYMCRYPT_CALL1134SymCryptSha1Selftest(void);11351136extern const PCSYMCRYPT_HASH SymCryptSha1Algorithm;11371138////////////////////////////////////////////////////////////////////////////1139// SHA-2241140//1141//1142// The SHA-224 hash algorithm per FIPS 180-4.1143// This implementation is limited to data strings that are in whole bytes.1144// Odd bit length are not supported.1145//1146// The SHA-224 standard limits data inputs to a maximum of 2^61-1 bytes.1147// This implementation supports larger inputs, and simply wraps the internal message1148// length counter. Note that the security properties are unknown for1149// such long messages, and their use is not recommended.1150//1151// This implementation is meant for interoperability and is not recommended for use.1152//1153// For details on this API see the description above about the generic hash function API.1154//11551156#define SYMCRYPT_SHA224_RESULT_SIZE (28)1157#define SYMCRYPT_SHA224_INPUT_BLOCK_SIZE (64)11581159VOID1160SYMCRYPT_CALL1161SymCryptSha224(1162_In_reads_( cbData ) PCBYTE pbData,1163SIZE_T cbData,1164_Out_writes_( SYMCRYPT_SHA224_RESULT_SIZE ) PBYTE pbResult );11651166VOID1167SYMCRYPT_CALL1168SymCryptSha224Init( _Out_ PSYMCRYPT_SHA224_STATE pState );11691170VOID1171SYMCRYPT_CALL1172SymCryptSha224Append(1173_Inout_ PSYMCRYPT_SHA224_STATE pState,1174_In_reads_( cbData ) PCBYTE pbData,1175SIZE_T cbData );11761177VOID1178SYMCRYPT_CALL1179SymCryptSha224Result(1180_Inout_ PSYMCRYPT_SHA224_STATE pState,1181_Out_writes_( SYMCRYPT_SHA224_RESULT_SIZE ) PBYTE pbResult );11821183VOID1184SYMCRYPT_CALL1185SymCryptSha224StateCopy( _In_ PCSYMCRYPT_SHA224_STATE pSrc, _Out_ PSYMCRYPT_SHA224_STATE pDst );11861187VOID1188SYMCRYPT_CALL1189SymCryptSha224StateExport(1190_In_ PCSYMCRYPT_SHA224_STATE pState,1191_Out_writes_bytes_( SYMCRYPT_SHA224_STATE_EXPORT_SIZE ) PBYTE pbBlob );11921193SYMCRYPT_ERROR1194SYMCRYPT_CALL1195SymCryptSha224StateImport(1196_Out_ PSYMCRYPT_SHA224_STATE pState,1197_In_reads_bytes_( SYMCRYPT_SHA224_STATE_EXPORT_SIZE) PCBYTE pbBlob );11981199VOID1200SYMCRYPT_CALL1201SymCryptSha224Selftest(void);12021203extern const PCSYMCRYPT_HASH SymCryptSha224Algorithm;12041205////////////////////////////////////////////////////////////////////////////1206// SHA-2561207//1208//1209// The SHA-256 hash algorithm per FIPS 180-4.1210// This implementation is limited to data strings that are in whole bytes.1211// Odd bit length are not supported.1212//1213// The SHA-256 standard limits data inputs to a maximum of 2^61-1 bytes.1214// This implementation supports larger inputs, and simply wraps the internal message1215// length counter. Note that the security properties are unknown for1216// such long messages, and their use is not recommended.1217//1218// For details on this API see the description above about the generic hash function API.1219//12201221#define SYMCRYPT_SHA256_RESULT_SIZE (32)1222#define SYMCRYPT_SHA256_INPUT_BLOCK_SIZE (64)12231224VOID1225SYMCRYPT_CALL1226SymCryptSha256(1227_In_reads_( cbData ) PCBYTE pbData,1228SIZE_T cbData,1229_Out_writes_( SYMCRYPT_SHA256_RESULT_SIZE ) PBYTE pbResult );12301231VOID1232SYMCRYPT_CALL1233SymCryptSha256Init( _Out_ PSYMCRYPT_SHA256_STATE pState );12341235VOID1236SYMCRYPT_CALL1237SymCryptSha256Append(1238_Inout_ PSYMCRYPT_SHA256_STATE pState,1239_In_reads_( cbData ) PCBYTE pbData,1240SIZE_T cbData );12411242VOID1243SYMCRYPT_CALL1244SymCryptSha256Result(1245_Inout_ PSYMCRYPT_SHA256_STATE pState,1246_Out_writes_( SYMCRYPT_SHA256_RESULT_SIZE ) PBYTE pbResult );12471248VOID1249SYMCRYPT_CALL1250SymCryptSha256StateCopy( _In_ PCSYMCRYPT_SHA256_STATE pSrc, _Out_ PSYMCRYPT_SHA256_STATE pDst );12511252VOID1253SYMCRYPT_CALL1254SymCryptSha256StateExport(1255_In_ PCSYMCRYPT_SHA256_STATE pState,1256_Out_writes_bytes_( SYMCRYPT_SHA256_STATE_EXPORT_SIZE ) PBYTE pbBlob );12571258SYMCRYPT_ERROR1259SYMCRYPT_CALL1260SymCryptSha256StateImport(1261_Out_ PSYMCRYPT_SHA256_STATE pState,1262_In_reads_bytes_( SYMCRYPT_SHA256_STATE_EXPORT_SIZE) PCBYTE pbBlob );12631264VOID1265SYMCRYPT_CALL1266SymCryptSha256Selftest(void);12671268extern const PCSYMCRYPT_HASH SymCryptSha256Algorithm;12691270////////////////////////////////////////////////////////////////////////////1271// SHA-3841272//1273//1274// The SHA-384 hash algorithm per FIPS 180-4.1275// This implementation is limited to data strings that are in whole bytes.1276// Odd bit length are not supported.1277//1278// The SHA-384 standard limits data inputs to a maximum of 2^125-1 bytes.1279// This implementation supports larger inputs, and simply wraps the internal message1280// length counter. Note that the security properties are unknown for1281// such long messages, and their use is not recommended.1282//1283// For details on this API see the description above about the generic hash function API.1284//12851286#define SYMCRYPT_SHA384_RESULT_SIZE (48)1287#define SYMCRYPT_SHA384_INPUT_BLOCK_SIZE (128)12881289VOID1290SYMCRYPT_CALL1291SymCryptSha384(1292_In_reads_( cbData ) PCBYTE pbData,1293SIZE_T cbData,1294_Out_writes_( SYMCRYPT_SHA384_RESULT_SIZE ) PBYTE pbResult );12951296VOID1297SYMCRYPT_CALL1298SymCryptSha384Init( _Out_ PSYMCRYPT_SHA384_STATE pState );12991300VOID1301SYMCRYPT_CALL1302SymCryptSha384Append(1303_Inout_ PSYMCRYPT_SHA384_STATE pState,1304_In_reads_( cbData ) PCBYTE pbData,1305SIZE_T cbData );13061307VOID1308SYMCRYPT_CALL1309SymCryptSha384Result(1310_Inout_ PSYMCRYPT_SHA384_STATE pState,1311_Out_writes_( SYMCRYPT_SHA384_RESULT_SIZE ) PBYTE pbResult );13121313VOID1314SYMCRYPT_CALL1315SymCryptSha384StateCopy( _In_ PCSYMCRYPT_SHA384_STATE pSrc, _Out_ PSYMCRYPT_SHA384_STATE pDst );13161317VOID1318SYMCRYPT_CALL1319SymCryptSha384StateExport(1320_In_ PCSYMCRYPT_SHA384_STATE pState,1321_Out_writes_bytes_( SYMCRYPT_SHA384_STATE_EXPORT_SIZE ) PBYTE pbBlob );13221323SYMCRYPT_ERROR1324SYMCRYPT_CALL1325SymCryptSha384StateImport(1326_Out_ PSYMCRYPT_SHA384_STATE pState,1327_In_reads_bytes_( SYMCRYPT_SHA384_STATE_EXPORT_SIZE) PCBYTE pbBlob );13281329VOID1330SYMCRYPT_CALL1331SymCryptSha384Selftest(void);13321333extern const PCSYMCRYPT_HASH SymCryptSha384Algorithm;13341335////////////////////////////////////////////////////////////////////////////1336// SHA-5121337//1338//1339// The SHA-512 hash algorithm per FIPS 180-4.1340// This implementation is limited to data strings that are in whole bytes.1341// Odd bit length are not supported.1342//1343// The SHA-512 standard limits data inputs to a maximum of 2^125-1 bytes.1344// This implementation supports larger inputs, and simply wraps the internal message1345// length counter. Note that the security properties are unknown for1346// such long messages, and their use is not recommended.1347//1348// For details on this API see the description above about the generic hash function API.1349//13501351#define SYMCRYPT_SHA512_RESULT_SIZE (64)1352#define SYMCRYPT_SHA512_INPUT_BLOCK_SIZE (128)13531354VOID1355SYMCRYPT_CALL1356SymCryptSha512(1357_In_reads_( cbData ) PCBYTE pbData,1358SIZE_T cbData,1359_Out_writes_( SYMCRYPT_SHA512_RESULT_SIZE ) PBYTE pbResult );13601361VOID1362SYMCRYPT_CALL1363SymCryptSha512Init( _Out_ PSYMCRYPT_SHA512_STATE pState );13641365VOID1366SYMCRYPT_CALL1367SymCryptSha512Append(1368_Inout_ PSYMCRYPT_SHA512_STATE pState,1369_In_reads_( cbData ) PCBYTE pbData,1370SIZE_T cbData );13711372VOID1373SYMCRYPT_CALL1374SymCryptSha512Result(1375_Inout_ PSYMCRYPT_SHA512_STATE pState,1376_Out_writes_( SYMCRYPT_SHA512_RESULT_SIZE ) PBYTE pbResult );13771378VOID1379SYMCRYPT_CALL1380SymCryptSha512StateCopy( _In_ PCSYMCRYPT_SHA512_STATE pSrc, _Out_ PSYMCRYPT_SHA512_STATE pDst );13811382VOID1383SYMCRYPT_CALL1384SymCryptSha512StateExport(1385_In_ PCSYMCRYPT_SHA512_STATE pState,1386_Out_writes_bytes_( SYMCRYPT_SHA512_STATE_EXPORT_SIZE ) PBYTE pbBlob );13871388SYMCRYPT_ERROR1389SYMCRYPT_CALL1390SymCryptSha512StateImport(1391_Out_ PSYMCRYPT_SHA512_STATE pState,1392_In_reads_bytes_( SYMCRYPT_SHA512_STATE_EXPORT_SIZE) PCBYTE pbBlob );13931394VOID1395SYMCRYPT_CALL1396SymCryptSha512Selftest(void);13971398extern const PCSYMCRYPT_HASH SymCryptSha512Algorithm;139914001401////////////////////////////////////////////////////////////////////////////1402// SHA-512/2241403//1404//1405// The SHA-512/224 hash algorithm per FIPS 180-4.1406// This implementation is limited to data strings that are in whole bytes.1407// Odd bit length are not supported.1408//1409// The SHA-512/224 standard limits data inputs to a maximum of 2^125-1 bytes.1410// This implementation supports larger inputs, and simply wraps the internal message1411// length counter. Note that the security properties are unknown for1412// such long messages, and their use is not recommended.1413//1414// This implementation is meant for interoperability and is not recommended for use.1415//1416// For details on this API see the description above about the generic hash function API.1417//14181419#define SYMCRYPT_SHA512_224_RESULT_SIZE (28)1420#define SYMCRYPT_SHA512_224_INPUT_BLOCK_SIZE (128)14211422VOID1423SYMCRYPT_CALL1424SymCryptSha512_224(1425_In_reads_( cbData ) PCBYTE pbData,1426SIZE_T cbData,1427_Out_writes_( SYMCRYPT_SHA512_224_RESULT_SIZE ) PBYTE pbResult );14281429VOID1430SYMCRYPT_CALL1431SymCryptSha512_224Init( _Out_ PSYMCRYPT_SHA512_224_STATE pState );14321433VOID1434SYMCRYPT_CALL1435SymCryptSha512_224Append(1436_Inout_ PSYMCRYPT_SHA512_224_STATE pState,1437_In_reads_( cbData ) PCBYTE pbData,1438SIZE_T cbData );14391440VOID1441SYMCRYPT_CALL1442SymCryptSha512_224Result(1443_Inout_ PSYMCRYPT_SHA512_224_STATE pState,1444_Out_writes_( SYMCRYPT_SHA512_224_RESULT_SIZE ) PBYTE pbResult );14451446VOID1447SYMCRYPT_CALL1448SymCryptSha512_224StateCopy( _In_ PCSYMCRYPT_SHA512_224_STATE pSrc, _Out_ PSYMCRYPT_SHA512_224_STATE pDst );14491450VOID1451SYMCRYPT_CALL1452SymCryptSha512_224StateExport(1453_In_ PCSYMCRYPT_SHA512_224_STATE pState,1454_Out_writes_bytes_( SYMCRYPT_SHA512_224_STATE_EXPORT_SIZE ) PBYTE pbBlob );14551456SYMCRYPT_ERROR1457SYMCRYPT_CALL1458SymCryptSha512_224StateImport(1459_Out_ PSYMCRYPT_SHA512_224_STATE pState,1460_In_reads_bytes_( SYMCRYPT_SHA512_224_STATE_EXPORT_SIZE) PCBYTE pbBlob );14611462VOID1463SYMCRYPT_CALL1464SymCryptSha512_224Selftest(void);14651466extern const PCSYMCRYPT_HASH SymCryptSha512_224Algorithm;146714681469////////////////////////////////////////////////////////////////////////////1470// SHA-512/2561471//1472//1473// The SHA-512/256 hash algorithm per FIPS 180-4.1474// This implementation is limited to data strings that are in whole bytes.1475// Odd bit length are not supported.1476//1477// The SHA-512/256 standard limits data inputs to a maximum of 2^125-1 bytes.1478// This implementation supports larger inputs, and simply wraps the internal message1479// length counter. Note that the security properties are unknown for1480// such long messages, and their use is not recommended.1481//1482// This implementation is meant for interoperability and is not recommended for use.1483//1484// For details on this API see the description above about the generic hash function API.1485//14861487#define SYMCRYPT_SHA512_256_RESULT_SIZE (32)1488#define SYMCRYPT_SHA512_256_INPUT_BLOCK_SIZE (128)14891490VOID1491SYMCRYPT_CALL1492SymCryptSha512_256(1493_In_reads_( cbData ) PCBYTE pbData,1494SIZE_T cbData,1495_Out_writes_( SYMCRYPT_SHA512_256_RESULT_SIZE ) PBYTE pbResult );14961497VOID1498SYMCRYPT_CALL1499SymCryptSha512_256Init( _Out_ PSYMCRYPT_SHA512_256_STATE pState );15001501VOID1502SYMCRYPT_CALL1503SymCryptSha512_256Append(1504_Inout_ PSYMCRYPT_SHA512_256_STATE pState,1505_In_reads_( cbData ) PCBYTE pbData,1506SIZE_T cbData );15071508VOID1509SYMCRYPT_CALL1510SymCryptSha512_256Result(1511_Inout_ PSYMCRYPT_SHA512_256_STATE pState,1512_Out_writes_( SYMCRYPT_SHA512_256_RESULT_SIZE ) PBYTE pbResult );15131514VOID1515SYMCRYPT_CALL1516SymCryptSha512_256StateCopy( _In_ PCSYMCRYPT_SHA512_256_STATE pSrc, _Out_ PSYMCRYPT_SHA512_256_STATE pDst );15171518VOID1519SYMCRYPT_CALL1520SymCryptSha512_256StateExport(1521_In_ PCSYMCRYPT_SHA512_256_STATE pState,1522_Out_writes_bytes_( SYMCRYPT_SHA512_256_STATE_EXPORT_SIZE ) PBYTE pbBlob );15231524SYMCRYPT_ERROR1525SYMCRYPT_CALL1526SymCryptSha512_256StateImport(1527_Out_ PSYMCRYPT_SHA512_256_STATE pState,1528_In_reads_bytes_( SYMCRYPT_SHA512_256_STATE_EXPORT_SIZE) PCBYTE pbBlob );15291530VOID1531SYMCRYPT_CALL1532SymCryptSha512_256Selftest(void);15331534extern const PCSYMCRYPT_HASH SymCryptSha512_256Algorithm;153515361537////////////////////////////////////////////////////////////////////////////1538// SHA-31539//1540// The SHA-3 family of hash algorithms per FIPS 202.1541// This implementation is limited to data strings that are in whole bytes.1542// Odd bit length are not supported.1543//1544// SHA3-224 is meant for interoperability and is not recommended for use.1545//1546// SHA3-224(M) = KECCAK[448](M || 01, 224)1547// SHA3-256(M) = KECCAK[512](M || 01, 256)1548// SHA3-384(M) = KECCAK[768](M || 01, 384)1549// SHA3-512(M) = KECCAK[1024](M || 01, 512)1550//1551// For details on this API see the description above about the generic hash function API.1552//155315541555//1556// SHA-3-2241557//15581559#define SYMCRYPT_SHA3_224_RESULT_SIZE (28)1560#define SYMCRYPT_SHA3_224_INPUT_BLOCK_SIZE (144)15611562VOID1563SYMCRYPT_CALL1564SymCryptSha3_224(1565_In_reads_(cbData) PCBYTE pbData,1566SIZE_T cbData,1567_Out_writes_(SYMCRYPT_SHA3_224_RESULT_SIZE) PBYTE pbResult);15681569VOID1570SYMCRYPT_CALL1571SymCryptSha3_224Init(_Out_ PSYMCRYPT_SHA3_224_STATE pState);15721573VOID1574SYMCRYPT_CALL1575SymCryptSha3_224Append(1576_Inout_ PSYMCRYPT_SHA3_224_STATE pState,1577_In_reads_(cbData) PCBYTE pbData,1578SIZE_T cbData);15791580VOID1581SYMCRYPT_CALL1582SymCryptSha3_224Result(1583_Inout_ PSYMCRYPT_SHA3_224_STATE pState,1584_Out_writes_(SYMCRYPT_SHA3_224_RESULT_SIZE) PBYTE pbResult);15851586VOID1587SYMCRYPT_CALL1588SymCryptSha3_224StateCopy(_In_ PCSYMCRYPT_SHA3_224_STATE pSrc, _Out_ PSYMCRYPT_SHA3_224_STATE pDst);15891590VOID1591SYMCRYPT_CALL1592SymCryptSha3_224StateExport(1593_In_ PCSYMCRYPT_SHA3_224_STATE pState,1594_Out_writes_bytes_(SYMCRYPT_SHA3_224_STATE_EXPORT_SIZE) PBYTE pbBlob);15951596SYMCRYPT_ERROR1597SYMCRYPT_CALL1598SymCryptSha3_224StateImport(1599_Out_ PSYMCRYPT_SHA3_224_STATE pState,1600_In_reads_bytes_(SYMCRYPT_SHA3_224_STATE_EXPORT_SIZE) PCBYTE pbBlob);16011602VOID1603SYMCRYPT_CALL1604SymCryptSha3_224Selftest(void);16051606extern const PCSYMCRYPT_HASH SymCryptSha3_224Algorithm;160716081609//1610// SHA-3-2561611//16121613#define SYMCRYPT_SHA3_256_RESULT_SIZE (32)1614#define SYMCRYPT_SHA3_256_INPUT_BLOCK_SIZE (136)16151616VOID1617SYMCRYPT_CALL1618SymCryptSha3_256(1619_In_reads_(cbData) PCBYTE pbData,1620SIZE_T cbData,1621_Out_writes_(SYMCRYPT_SHA3_256_RESULT_SIZE) PBYTE pbResult);16221623VOID1624SYMCRYPT_CALL1625SymCryptSha3_256Init(_Out_ PSYMCRYPT_SHA3_256_STATE pState);16261627VOID1628SYMCRYPT_CALL1629SymCryptSha3_256Append(1630_Inout_ PSYMCRYPT_SHA3_256_STATE pState,1631_In_reads_(cbData) PCBYTE pbData,1632SIZE_T cbData);16331634VOID1635SYMCRYPT_CALL1636SymCryptSha3_256Result(1637_Inout_ PSYMCRYPT_SHA3_256_STATE pState,1638_Out_writes_(SYMCRYPT_SHA3_256_RESULT_SIZE) PBYTE pbResult);16391640VOID1641SYMCRYPT_CALL1642SymCryptSha3_256StateCopy(_In_ PCSYMCRYPT_SHA3_256_STATE pSrc, _Out_ PSYMCRYPT_SHA3_256_STATE pDst);16431644VOID1645SYMCRYPT_CALL1646SymCryptSha3_256StateExport(1647_In_ PCSYMCRYPT_SHA3_256_STATE pState,1648_Out_writes_bytes_(SYMCRYPT_SHA3_256_STATE_EXPORT_SIZE) PBYTE pbBlob);16491650SYMCRYPT_ERROR1651SYMCRYPT_CALL1652SymCryptSha3_256StateImport(1653_Out_ PSYMCRYPT_SHA3_256_STATE pState,1654_In_reads_bytes_(SYMCRYPT_SHA3_256_STATE_EXPORT_SIZE) PCBYTE pbBlob);16551656VOID1657SYMCRYPT_CALL1658SymCryptSha3_256Selftest(void);16591660extern const PCSYMCRYPT_HASH SymCryptSha3_256Algorithm;166116621663//1664// SHA-3-3841665//16661667#define SYMCRYPT_SHA3_384_RESULT_SIZE (48)1668#define SYMCRYPT_SHA3_384_INPUT_BLOCK_SIZE (104)16691670VOID1671SYMCRYPT_CALL1672SymCryptSha3_384(1673_In_reads_(cbData) PCBYTE pbData,1674SIZE_T cbData,1675_Out_writes_(SYMCRYPT_SHA3_384_RESULT_SIZE) PBYTE pbResult);16761677VOID1678SYMCRYPT_CALL1679SymCryptSha3_384Init(_Out_ PSYMCRYPT_SHA3_384_STATE pState);16801681VOID1682SYMCRYPT_CALL1683SymCryptSha3_384Append(1684_Inout_ PSYMCRYPT_SHA3_384_STATE pState,1685_In_reads_(cbData) PCBYTE pbData,1686SIZE_T cbData);16871688VOID1689SYMCRYPT_CALL1690SymCryptSha3_384Result(1691_Inout_ PSYMCRYPT_SHA3_384_STATE pState,1692_Out_writes_(SYMCRYPT_SHA3_384_RESULT_SIZE) PBYTE pbResult);16931694VOID1695SYMCRYPT_CALL1696SymCryptSha3_384StateCopy(_In_ PCSYMCRYPT_SHA3_384_STATE pSrc, _Out_ PSYMCRYPT_SHA3_384_STATE pDst);16971698VOID1699SYMCRYPT_CALL1700SymCryptSha3_384StateExport(1701_In_ PCSYMCRYPT_SHA3_384_STATE pState,1702_Out_writes_bytes_(SYMCRYPT_SHA3_384_STATE_EXPORT_SIZE) PBYTE pbBlob);17031704SYMCRYPT_ERROR1705SYMCRYPT_CALL1706SymCryptSha3_384StateImport(1707_Out_ PSYMCRYPT_SHA3_384_STATE pState,1708_In_reads_bytes_(SYMCRYPT_SHA3_384_STATE_EXPORT_SIZE) PCBYTE pbBlob);17091710VOID1711SYMCRYPT_CALL1712SymCryptSha3_384Selftest(void);17131714extern const PCSYMCRYPT_HASH SymCryptSha3_384Algorithm;171517161717//1718// SHA-3-5121719//17201721#define SYMCRYPT_SHA3_512_RESULT_SIZE (64)1722#define SYMCRYPT_SHA3_512_INPUT_BLOCK_SIZE (72)17231724VOID1725SYMCRYPT_CALL1726SymCryptSha3_512(1727_In_reads_( cbData ) PCBYTE pbData,1728SIZE_T cbData,1729_Out_writes_( SYMCRYPT_SHA3_512_RESULT_SIZE ) PBYTE pbResult );17301731VOID1732SYMCRYPT_CALL1733SymCryptSha3_512Init( _Out_ PSYMCRYPT_SHA3_512_STATE pState );17341735VOID1736SYMCRYPT_CALL1737SymCryptSha3_512Append(1738_Inout_ PSYMCRYPT_SHA3_512_STATE pState,1739_In_reads_( cbData ) PCBYTE pbData,1740SIZE_T cbData );17411742VOID1743SYMCRYPT_CALL1744SymCryptSha3_512Result(1745_Inout_ PSYMCRYPT_SHA3_512_STATE pState,1746_Out_writes_( SYMCRYPT_SHA3_512_RESULT_SIZE ) PBYTE pbResult );17471748VOID1749SYMCRYPT_CALL1750SymCryptSha3_512StateCopy( _In_ PCSYMCRYPT_SHA3_512_STATE pSrc, _Out_ PSYMCRYPT_SHA3_512_STATE pDst );17511752VOID1753SYMCRYPT_CALL1754SymCryptSha3_512StateExport(1755_In_ PCSYMCRYPT_SHA3_512_STATE pState,1756_Out_writes_bytes_( SYMCRYPT_SHA3_512_STATE_EXPORT_SIZE ) PBYTE pbBlob );17571758SYMCRYPT_ERROR1759SYMCRYPT_CALL1760SymCryptSha3_512StateImport(1761_Out_ PSYMCRYPT_SHA3_512_STATE pState,1762_In_reads_bytes_( SYMCRYPT_SHA3_512_STATE_EXPORT_SIZE) PCBYTE pbBlob );17631764VOID1765SYMCRYPT_CALL1766SymCryptSha3_512Selftest(void);17671768extern const PCSYMCRYPT_HASH SymCryptSha3_512Algorithm;176917701771//==========================================================================1772// Extendable-Output Functions (XOFs)1773//==========================================================================1774//1775// XOFs are similar to hash functions except that the output can be arbitrary length.1776// SHAKE128 and SHAKE256 are XOFs specified in FIPS 202.1777//1778// SHAKE128(M, d) = KECCAK[256] (M || 1111, d)1779// SHAKE256(M, d) = KECCAK[512] (M || 1111, d)1780//1781// SHAKEs share the same Keccak state as the other Keccak based algorithms under1782// the name SYMCRYPT_SHAKEXxx_STATE.1783//1784// Both SHAKE128 and SHAKE256 have default result sizes (32- and 64-bytes resp.)1785// that allows them to be used as substitutes for hash functions with the Init-Append-Result1786// pattern.1787//1788// Extract is a new type of function that does not exist in hash functions, which can1789// be called multiple times to successively generate output from the state. Extract1790// function also provides the caller with a flag to wipe the state when no further Extract1791// calls will be made. If the caller does not know in advance whether an Extract call is1792// the final one, wiping can be performed later with an Init call or an Extract call with1793// zero bytes output.1794//1795// If Append is called after an Extract call which did not wipe the state (i.e., the state1796// is still in 'extract' mode), Append will notice this and switch from 'extract' mode to1797// 'append' mode by wiping and initializing the state. This Append call effectively appends1798// data for a fresh computation, saving an additional call to wipe/initialize the state.1799//1800//1801// SYMCRYPT_SHAKEXXX_RESULT_SIZE1802//1803// Default output size, used by the SymCryptShakeXxxResult function.1804//1805// SYMCRYPT_SHAKEXXX_INPUT_BLOCK_SIZE1806//1807// Rate for the Keccak permutation.1808//1809// VOID1810// SYMCRYPT_CALL1811// SymCryptShakeXxxDefault(1812// _In_reads_( cbData ) PCBYTE pbData,1813// SIZE_T cbData,1814// _Out_writes_( SYMCRYPT_SHAKEXXX_RESULT_SIZE ) PBYTE pbResult);1815//1816// SHAKE single-call function that produces default output size defined by1817// SYMCRYPT_SHAKEXXX_RESULT_SIZE.1818//1819// VOID1820// SYMCRYPT_CALL1821// SymCryptShakeXxx(1822// _In_reads_( cbData ) PCBYTE pbData,1823// SIZE_T cbData,1824// _Out_writes_( cbResult ) PBYTE pbResult,1825// SIZE_T cbResult);1826//1827// SHAKE single-call function that produces variable-length output specified1828// by the cbResult parameter.1829//1830// VOID1831// SYMCRYPT_CALL1832// SymCryptShakeXxxInit( _Out_ PSYMCRYPT_XXX_STATE pState );1833//1834// Initializes the SHAKE state.1835//1836// VOID1837// SYMCRYPT_CALL1838// SymCryptShakeXxxAppend(1839// _Inout_ PSYMCRYPT_XXX_STATE pState,1840// _In_reads_( cbData ) PCBYTE pbData,1841// SIZE_T cbData );1842//1843// Appends data to the SHAKE state.1844//1845// Append cannot be the first call to an uninitialized SHAKE state. All1846// other uses independent of whether the state is in 'append' mode or 'extract'1847// mode are well defined. If the state was previously in 'extract' mode, (i.e., after1848// an Extract call with bWipe=FALSE) it wipes/resets the state and the data is1849// appended to a fresh state.1850//1851// VOID1852// SYMCRYPT_CALL1853// SymCryptShakeXxxExtract(1854// _Inout_ PSYMCRYPT_XXX_STATE pState,1855// _Out_writes_(cbResult) PBYTE pbResult,1856// SIZE_T cbResult,1857// BOOLEAN bWipe);1858//1859// Generates output from the SHAKE state.1860//1861// Extract cannot be the first call to an uninitialized SHAKE state. All1862// other uses independent of whether the state is in 'append' mode or 'extract' mode1863// are well defined.1864//1865// If the state was in 'append' mode before the Extract call, Extract switches1866// the state to 'extract' mode and generates the requested number of bytes from1867// the state. Extract wipes/resets the state and transitions the state to 'append'1868// mode if bWipe=TRUE, otherwise leaving the state in 'extract' mode, available for1869// further extractions.1870//1871// VOID1872// SYMCRYPT_CALL1873// SymCryptShakeXxxResult(1874// _Inout_ PSYMCRYPT_XXX_STATE pState,1875// _Out_writes_(SYMCRYPT_SHAKEXXX_RESULT_SIZE) PBYTE pbResult );1876//1877// Extracts SYMCRYPT_SHAKEXXX_RESULT_SIZE bytes from the state and wipes/resets1878// it for a new computation.1879//1880// Result cannot be called with an uninitialized state. All other uses are well1881// defined. If it is called after an Extract call with bWipe=FALSE, it does the1882// final extraction from the state for SYMCRYPT_SHAKEXXX_RESULT_SIZE bytes,1883// effectively calling Extract with cbResult=SYMCRYPT_SHAKEXXX_RESULT_SIZE and1884// bWipe=TRUE.1885//1886// VOID1887// SYMCRYPT_CALL1888// SymCryptShakeXxxStateCopy(_In_ PCSYMCRYPT_SHAKEXXX_STATE pSrc, _Out_ PSYMCRYPT_SHAKEXXX_STATE pDst);1889//1890// Create a new copy of the state object.1891//1892// VOID1893// SYMCRYPT_CALL1894// SymCryptShakeXxxSelftest(void);1895//1896// Perform a minimal self-test on the ShakeXxx algorithm.1897// This function is designed to be used for achieving FIPS 140-2 compliance or1898// to provide a simple self-test when an application starts.1899//1900// If an error is detected, a platform-specific fatal error action is taken.1901// Callers do not need to handle any error conditions.190219031904//1905// SHAKE1281906//1907#define SYMCRYPT_SHAKE128_RESULT_SIZE (32)1908#define SYMCRYPT_SHAKE128_INPUT_BLOCK_SIZE (168)19091910VOID1911SYMCRYPT_CALL1912SymCryptShake128Default(1913_In_reads_( cbData ) PCBYTE pbData,1914SIZE_T cbData,1915_Out_writes_( SYMCRYPT_SHAKE128_RESULT_SIZE ) PBYTE pbResult);19161917VOID1918SYMCRYPT_CALL1919SymCryptShake128(1920_In_reads_( cbData ) PCBYTE pbData,1921SIZE_T cbData,1922_Out_writes_( cbResult ) PBYTE pbResult,1923SIZE_T cbResult);19241925VOID1926SYMCRYPT_CALL1927SymCryptShake128Init( _Out_ PSYMCRYPT_SHAKE128_STATE pState );19281929VOID1930SYMCRYPT_CALL1931SymCryptShake128Append(1932_Inout_ PSYMCRYPT_SHAKE128_STATE pState,1933_In_reads_( cbData ) PCBYTE pbData,1934SIZE_T cbData );19351936VOID1937SYMCRYPT_CALL1938SymCryptShake128Extract(1939_Inout_ PSYMCRYPT_SHAKE128_STATE pState,1940_Out_writes_(cbResult) PBYTE pbResult,1941SIZE_T cbResult,1942BOOLEAN bWipe);19431944VOID1945SYMCRYPT_CALL1946SymCryptShake128Result(1947_Inout_ PSYMCRYPT_SHAKE128_STATE pState,1948_Out_writes_(SYMCRYPT_SHAKE128_RESULT_SIZE) PBYTE pbResult );19491950VOID1951SYMCRYPT_CALL1952SymCryptShake128StateCopy(_In_ PCSYMCRYPT_SHAKE128_STATE pSrc, _Out_ PSYMCRYPT_SHAKE128_STATE pDst);19531954VOID1955SYMCRYPT_CALL1956SymCryptShake128Selftest(void);19571958extern const PCSYMCRYPT_HASH SymCryptShake128HashAlgorithm;19591960//1961// SHAKE2561962//1963#define SYMCRYPT_SHAKE256_RESULT_SIZE (64)1964#define SYMCRYPT_SHAKE256_INPUT_BLOCK_SIZE (136)19651966VOID1967SYMCRYPT_CALL1968SymCryptShake256Default(1969_In_reads_( cbData ) PCBYTE pbData,1970SIZE_T cbData,1971_Out_writes_( SYMCRYPT_SHAKE256_RESULT_SIZE ) PBYTE pbResult);19721973VOID1974SYMCRYPT_CALL1975SymCryptShake256(1976_In_reads_( cbData ) PCBYTE pbData,1977SIZE_T cbData,1978_Out_writes_( cbResult ) PBYTE pbResult,1979SIZE_T cbResult);19801981VOID1982SYMCRYPT_CALL1983SymCryptShake256Init( _Out_ PSYMCRYPT_SHAKE256_STATE pState );19841985VOID1986SYMCRYPT_CALL1987SymCryptShake256Append(1988_Inout_ PSYMCRYPT_SHAKE256_STATE pState,1989_In_reads_( cbData ) PCBYTE pbData,1990SIZE_T cbData );19911992VOID1993SYMCRYPT_CALL1994SymCryptShake256Extract(1995_Inout_ PSYMCRYPT_SHAKE256_STATE pState,1996_Out_writes_(cbResult) PBYTE pbResult,1997SIZE_T cbResult,1998BOOLEAN bWipe);19992000VOID2001SYMCRYPT_CALL2002SymCryptShake256Result(2003_Inout_ PSYMCRYPT_SHAKE256_STATE pState,2004_Out_writes_(SYMCRYPT_SHAKE256_RESULT_SIZE) PBYTE pbResult );200520062007VOID2008SYMCRYPT_CALL2009SymCryptShake256StateCopy(_In_ PCSYMCRYPT_SHAKE256_STATE pSrc, _Out_ PSYMCRYPT_SHAKE256_STATE pDst);20102011VOID2012SYMCRYPT_CALL2013SymCryptShake256Selftest(void);20142015extern const PCSYMCRYPT_HASH SymCryptShake256HashAlgorithm;20162017//==========================================================================2018// Customizable Extendable-Output Functions (XOFs)2019//==========================================================================2020//2021// cSHAKE128 and cSHAKE256 are customizable SHAKE functions specified in NIST SP 800-185.2022//2023// When cSHAKE input strings N (function name string) and S (customization string) are2024// both empty, cSHAKE is equivalent to SHAKE:2025//2026// cSHAKE128(X, L, "", "") = SHAKE128(X, L)2027// cSHAKE256(X, L, "", "") = SHAKE256(X, L)2028//2029// If at least one of N and S is non-empty, cSHAKE is defined as follows:2030//2031// cSHAKE128(X, L, N, S) = KECCAK[256](bytepad(encode_string(N) || encode_string(S), 168) || X || 00, L)2032// cSHAKE256(X, L, N, S) = KECCAK[512](bytepad(encode_string(N) || encode_string(S), 136) || X || 00, L)2033//2034// The following functions are equivalent to their SHAKE counterparts.2035// SymCryptCShakeXxxExtract with bWipe=TRUE and SymCryptCShakeXxxResult functions reset2036// the cSHAKE state to an empty SHAKE state after generating output. This behavior is2037// equivalent to calling SymCryptCShakeXxxInit with empty input strings.2038//2039// SymCryptCShakeXxxAppend2040// SymCryptCShakeXxxExtract2041// SymCryptCShakeXxxResult2042//2043// Calling SymCryptCShakeXxxAppend when cSHAKE state is in 'extract' mode results2044// in the same behavior described above: the state is wiped and initialized with2045// empty input strings, after which the data is appended to the empty state. This2046// converts the state to a SHAKE state since cSHAKE with empty input strings is2047// equivalent to SHAKE. This is a consequence of not being able to store the input2048// strings to cSHAKE and re-initialize it with them. Thus, if multiple cSHAKE2049// computations with the same input strings are to be carried out, cSHAKE state must2050// be initialized with the input strings each time.2051//2052// The following functions differ from the SHAKE by the introduction of customization2053// strings:2054//2055// VOID2056// SYMCRYPT_CALL2057// SymCryptCShakeXxx(2058// _In_reads_( cbFunctionNameString ) PCBYTE pbFunctionNameString,2059// SIZE_T cbFunctionNameString,2060// _In_reads_( cbCustomizationString ) PCBYTE pbCustomizationString,2061// SIZE_T cbCustomizationString,2062// _In_reads_( cbData ) PCBYTE pbData,2063// SIZE_T cbData,2064// _Out_writes_( cbResult ) PBYTE pbResult,2065// SIZE_T cbResult);2066//2067// Single-call cSHAKE computation.2068//2069// VOID2070// SYMCRYPT_CALL2071// SymCryptCShakeXxxInit(2072// _Out_ PSYMCRYPT_CSHAKEXXX_STATE pState,2073// _In_reads_( cbFunctionNameString ) PCBYTE pbFunctionNameString,2074// SIZE_T cbFunctionNameString,2075// _In_reads_( cbCustomizationString ) PCBYTE pbCustomizationString,2076// SIZE_T cbCustomizationString);2077//2078// Initializes the cSHAKE state with the provided input strings. If both of2079// the input strings are empty, the call is equivalent to SymCryptShakeXxxInit,2080// otherwise the input strings will be encoded and appended to the state.208120822083//2084// cSHAKE1282085//2086#define SYMCRYPT_CSHAKE128_RESULT_SIZE SYMCRYPT_SHAKE128_RESULT_SIZE2087#define SYMCRYPT_CSHAKE128_INPUT_BLOCK_SIZE SYMCRYPT_SHAKE128_INPUT_BLOCK_SIZE20882089VOID2090SYMCRYPT_CALL2091SymCryptCShake128(2092_In_reads_( cbFunctionNameString ) PCBYTE pbFunctionNameString,2093SIZE_T cbFunctionNameString,2094_In_reads_( cbCustomizationString ) PCBYTE pbCustomizationString,2095SIZE_T cbCustomizationString,2096_In_reads_( cbData ) PCBYTE pbData,2097SIZE_T cbData,2098_Out_writes_( cbResult ) PBYTE pbResult,2099SIZE_T cbResult);21002101VOID2102SYMCRYPT_CALL2103SymCryptCShake128Init(2104_Out_ PSYMCRYPT_CSHAKE128_STATE pState,2105_In_reads_( cbFunctionNameString ) PCBYTE pbFunctionNameString,2106SIZE_T cbFunctionNameString,2107_In_reads_( cbCustomizationString ) PCBYTE pbCustomizationString,2108SIZE_T cbCustomizationString);21092110VOID2111SYMCRYPT_CALL2112SymCryptCShake128Append(2113_Inout_ PSYMCRYPT_CSHAKE128_STATE pState,2114_In_reads_( cbData ) PCBYTE pbData,2115SIZE_T cbData );21162117VOID2118SYMCRYPT_CALL2119SymCryptCShake128Extract(2120_Inout_ PSYMCRYPT_CSHAKE128_STATE pState,2121_Out_writes_(cbResult) PBYTE pbResult,2122SIZE_T cbResult,2123BOOLEAN bWipe);21242125VOID2126SYMCRYPT_CALL2127SymCryptCShake128Result(2128_Inout_ PSYMCRYPT_CSHAKE128_STATE pState,2129_Out_writes_( SYMCRYPT_CSHAKE128_RESULT_SIZE ) PBYTE pbResult);21302131VOID2132SYMCRYPT_CALL2133SymCryptCShake128StateCopy(_In_ PCSYMCRYPT_CSHAKE128_STATE pSrc, _Out_ PSYMCRYPT_CSHAKE128_STATE pDst);21342135VOID2136SYMCRYPT_CALL2137SymCryptCShake128Selftest(void);213821392140//2141// cSHAKE2562142//2143#define SYMCRYPT_CSHAKE256_RESULT_SIZE SYMCRYPT_SHAKE256_RESULT_SIZE2144#define SYMCRYPT_CSHAKE256_INPUT_BLOCK_SIZE SYMCRYPT_SHAKE256_INPUT_BLOCK_SIZE21452146VOID2147SYMCRYPT_CALL2148SymCryptCShake256(2149_In_reads_( cbFunctionNameString ) PCBYTE pbFunctionNameString,2150SIZE_T cbFunctionNameString,2151_In_reads_( cbCustomizationString ) PCBYTE pbCustomizationString,2152SIZE_T cbCustomizationString,2153_In_reads_( cbData ) PCBYTE pbData,2154SIZE_T cbData,2155_Out_writes_( cbResult ) PBYTE pbResult,2156SIZE_T cbResult);21572158VOID2159SYMCRYPT_CALL2160SymCryptCShake256Init(2161_Out_ PSYMCRYPT_CSHAKE256_STATE pState,2162_In_reads_( cbFunctionNameString ) PCBYTE pbFunctionNameString,2163SIZE_T cbFunctionNameString,2164_In_reads_( cbCustomizationString ) PCBYTE pbCustomizationString,2165SIZE_T cbCustomizationString);21662167VOID2168SYMCRYPT_CALL2169SymCryptCShake256Append(2170_Inout_ PSYMCRYPT_CSHAKE256_STATE pState,2171_In_reads_( cbData ) PCBYTE pbData,2172SIZE_T cbData );21732174VOID2175SYMCRYPT_CALL2176SymCryptCShake256Extract(2177_Inout_ PSYMCRYPT_CSHAKE256_STATE pState,2178_Out_writes_(cbResult) PBYTE pbResult,2179SIZE_T cbResult,2180BOOLEAN bWipe);21812182VOID2183SYMCRYPT_CALL2184SymCryptCShake256Result(2185_Inout_ PSYMCRYPT_CSHAKE256_STATE pState,2186_Out_writes_( SYMCRYPT_CSHAKE256_RESULT_SIZE ) PBYTE pbResult);21872188VOID2189SYMCRYPT_CALL2190SymCryptCShake256StateCopy(_In_ PCSYMCRYPT_CSHAKE256_STATE pSrc, _Out_ PSYMCRYPT_CSHAKE256_STATE pDst);21912192VOID2193SYMCRYPT_CALL2194SymCryptCShake256Selftest(void);2195219621972198//==========================================================================2199// PARALLELISED HASH FUNCTIONS2200//==========================================================================2201//2202// On some platforms it is possible to parallelize the hash function2203// computation to achieve a higher throughput.2204// The parallel hash APIs support this.2205// The parallel implementation tries to perform the computations as efficiently2206// as possible. Applications that have many hashes to compute can always call these2207// functions; the library will optimize the computation to the current situation.2208// For example, if only a single hash is computed using these APIs, the2209// single-hash version is used to achieve full single-hash speed.2210// On platforms that do not support parallel hash implementations, these functions2211// are still available, and will implement the parallel hashing by computing the2212// hashes one at a time.2213//2214//2215// SYMCRYPT_PARALLEL_XXX_MIN_PARALLELISM2216//2217// Compile-time constant, but can vary per platform.2218// Minimum number of parallel computations at which2219// the parallel implementation is faster on at least some CPU versions.2220// Applications can safely ask for parallel computations with fewer hashes,2221// but there will be no speed gain.2222//2223// SYMCRYPT_PARALLEL_XXX_MAX_PARALLELISM2224//2225// Maximum internal parallelism that the library uses internally on at least one2226// CPU version of this architecture.2227// If all hash computations are the same length, then there is no significant2228// benefit to providing more than this number of hash requests in parallel.2229// However, if the hash computations are of different lengths then the library2230// overlaps various hash computations and still gains efficiency when the2231// number of parallel hash computations increases past this bound.2232// Note that the internal parallelism that can be used might depend2233// on the CPU features available, so this value is only an upper bound.2234// We recommend that callers provide as much parallelism as practical,2235// and let the library perform the optimal sequence of computations.2236//2237// SYMCRYPT_HASH_OPERATION_TYPE2238//2239// An enum that specifies which operation is to be performed in a command2240// structure passed to a parallel hash operations function.2241// Defined values:2242// SYMCRYPT_HASH_OPERATION_APPEND;2243// SYMCRYPT_HASH_OPERATION_RESULT;2244//2245// SYMCRYPT_PARALLEL_HASH_OPERATION2246//2247// Structure that contains a command to be performed on a single item in a2248// parallel hash state array. Visible fields are:2249//2250// SIZE_T iHash; // index of hash object into the state array2251// SYMCRYPT_HASH_OPERATION_TYPE hashOperation; // operation to be performed2252// PBYTE pbBuffer; // data to be hashed, or result buffer2253// SIZE_T cbBuffer;2254//2255// There might be other fields in this structure that the caller should not use or assume anything about.2256//2257// SymCryptParallelXxxInit(2258// _Out_writes_( nStates ) PSYMCRYPT_XXX_STATE pStates,2259// SIZE_T nStates );2260// Initialize an array of hash states.2261// The elements of the array are normal hash states, and they can be2262// manipulated individually using the standard functions for the hash2263// algorithm.2264//2265// Functionally equivalent to:2266// for( i=0; i<nStates; i++ ) {2267// SymCryptXxxInit( &pStates[i] );2268// }2269//2270// It is not necessary to use this function to initialize a state array;2271// the normal initialization function can also be used, but this function might2272// be faster.2273//2274// SymCryptParallelXxxProcess(2275// _Inout_updates_( nStates ) PSYMCRYPT_XXX_STATE pStates,2276// SIZE_T nStates,2277// _Inout_updates_( nOperations ) PSYMCRYPT_PARALLEL_HASH_OPERATION pOperation,2278// SIZE_T nOperations,2279// _Out_writes_( cbScratch ) PBYTE pbScratch,2280// SIZE_T cbScratch );2281//2282// Perform optionally parallel processing of hashes.2283// This is functionally equivalent to iterating over the pOperations array in order,2284// and executing the command in each PARALLEL_HASH_OPERATION one at a time.2285// For each command:2286// iHash Which hash state this operation applies to; must be < nStates.2287// hashOperation Specifies whether this is an append or result operation.2288// pbBuffer The buffer that contains the data to be hashed, or that will receive the result.2289// cbBuffer The size of pbBuffer. (Must be equal to the hash algorithm result size for RESULT operations.)2290// As the SAL annotations document, the pOperations array is updated by this function, and therefore2291// it cannot be in read-only memory.2292// The updates modify only to the internal scratch space that is reserved2293// in the SYMCRYPT_PARALLEL_HASH_OPERATION structure; none of the documented fields2294// (iHash, hashOperation, pbBuffer, cbBuffer) are modified.2295// The scratch fields are used purely within one call to this function, their value does not have to be2296// maintained between function calls. The scratch fields do not have to be initialized by the caller2297// of this function,2298// THREAD SAFETY: as the pOperations array is updated, it CANNOT be shared between different threads.2299// Obviously, the same is true of pStates and pbScratch.2300//2301// The pbScratch pointer provides a scratch buffer for the parallel processing function.2302// This is used to organize the request and perform the functions in an optimal order for2303// maximum parallelism, and for storing intermediate results that are too large2304// to fit on the stack. The scratch buffer must be at least2305// SYMCRYPT_PARALLEL_XXX_FIXED_SCRATCH + nStates * SYMCRYPT_PARALLEL_HASH_PER_STATE_SCRATCH2306// bytes in size.2307//2308// For incremental hashing, we recommend that callers process data sizes that are2309// a multiple of the SYMCRYPT_XXX_INPUT_BLOCK_LEN.2310//231123122313VOID2314SYMCRYPT_CALL2315SymCryptParallelSha256Init(2316_Out_writes_( nStates ) PSYMCRYPT_SHA256_STATE pStates,2317SIZE_T nStates );23182319SYMCRYPT_ERROR2320SYMCRYPT_CALL2321SymCryptParallelSha256Process(2322_Inout_updates_( nStates ) PSYMCRYPT_SHA256_STATE pStates,2323SIZE_T nStates,2324_Inout_updates_( nOperations ) PSYMCRYPT_PARALLEL_HASH_OPERATION pOperations,2325SIZE_T nOperations,2326_Out_writes_( cbScratch ) PBYTE pbScratch,2327SIZE_T cbScratch );232823292330VOID2331SYMCRYPT_CALL2332SymCryptParallelSha384Init(2333_Out_writes_( nStates ) PSYMCRYPT_SHA384_STATE pStates,2334SIZE_T nStates );23352336SYMCRYPT_ERROR2337SYMCRYPT_CALL2338SymCryptParallelSha384Process(2339_Inout_updates_( nStates ) PSYMCRYPT_SHA384_STATE pStates,2340SIZE_T nStates,2341_Inout_updates_( nOperations ) PSYMCRYPT_PARALLEL_HASH_OPERATION pOperations,2342SIZE_T nOperations,2343_Out_writes_( cbScratch ) PBYTE pbScratch,2344SIZE_T cbScratch );234523462347VOID2348SYMCRYPT_CALL2349SymCryptParallelSha512Init(2350_Out_writes_( nStates ) PSYMCRYPT_SHA512_STATE pStates,2351SIZE_T nStates );23522353SYMCRYPT_ERROR2354SYMCRYPT_CALL2355SymCryptParallelSha512Process(2356_Inout_updates_( nStates ) PSYMCRYPT_SHA512_STATE pStates,2357SIZE_T nStates,2358_Inout_updates_( nOperations ) PSYMCRYPT_PARALLEL_HASH_OPERATION pOperations,2359SIZE_T nOperations,2360_Out_writes_( cbScratch ) PBYTE pbScratch,2361SIZE_T cbScratch );236223632364VOID2365SYMCRYPT_CALL2366SymCryptParallelSha256Selftest(void);23672368VOID2369SYMCRYPT_CALL2370SymCryptParallelSha384Selftest(void);23712372VOID2373SYMCRYPT_CALL2374SymCryptParallelSha512Selftest(void);2375237623772378//==========================================================================2379// MESSAGE AUTHENTICATION CODE (MAC)2380//==========================================================================2381//2382// All MAC functions have a similar interface. For consistency we describe2383// the generic parts of the interface once.2384// Algorithm-specific comments are given with the API functions of each algorithm separately.2385//2386// For a MAC algorithm called XXX the following functions, types, and constants are defined:2387//2388//2389// SYMCRYPT_XXX_RESULT_SIZE2390//2391// A constant giving is the size, in bytes, of the result of the MAC function.2392// Some applications use truncated MAC functions. These are not directly supported2393// by this library. Applications will have to perform the truncation themselves.2394//2395//2396// SYMCRYPT_XXX_INPUT_BLOCK_SIZE2397//2398// A constant giving the natural input block size for the MAC function.2399// Most callers don't need to know this, but in some cases it can be useful2400// for optimizations.2401//2402//2403// SYMCRYPT_XXX_EXPANDED_KEY2404//2405// Type which contains a key with all the pre-computations performed.2406// This is an opaque type whose structure can change at will.2407// It should only be used for transient computations in a single executable2408// and not be stored or transferred to a different environment.2409// The pointer and const-pointer versions are also declared2410// (PSYMCRYPOT_XXX_EXPANDED_KEY and PCSYMCRYPT_XXX_EXPANDED_KEY).2411//2412// The EXPANDED_KEY structure contains keying material and should be wiped2413// once it is no longer used. (See SymCryptWipe & SymCryptWipeKnownSize)2414//2415// Once a key has been expanded, multiple threads can simultaneously use the same expanded key2416// object for different MAC computations that use the same key as the expanded key2417// object does not change value.2418//2419//2420// SYMCRYPT_ERROR2421// SYMCRYPT_CALL2422// SymCryptXxxExpandKey( _Out_ PSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,2423// _In_reads_(cbKey) PCBYTE pbKey,2424// SIZE_T cbKey );2425//2426// Prepare a key for future use by the Xxx algorithm.2427// This function performs pre-computations on the key2428// to speed up the actual MAC computations later, and stores the result as an expanded key.2429// The expanded key must be kept unchanged until all MAC computations that use the key are finished.2430// When the key is no longer needed the expanded key structure should be wiped.2431//2432// Different algorithms pose different requirements on the length of the key.2433// If the key that is provided is of an unsupported length the SYMCRYPT_WRONG_KEY_SIZE error is returned.2434// In this case the expanded key structure will not contain any keying material and does not have to be wiped.2435//2436//2437// VOID2438// SYMCRYPT_CALL2439// SymCryptXxxKeyCopy( _In_ PCSYMCRYPT_XXX_EXPANDED_KEY pSrc,2440// _Out_ PSYMCRYPT_XXX_EXPANDED_KEY pDst );2441//2442// Create a copy of an expanded key.2443//2444// VOID2445// SYMCRYPT_CALL2446// SymCryptXxx( _In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,2447// _In_reads_( cbData ) PCBYTE pbData,2448// SIZE_T cbData,2449// _Out_writes_( SYMCRYPT_XXX_RESULT_SIZE ) PBYTE pbResult );2450//2451// Computes the MAC value of the data buffer with a given key.2452// If you have all the data to be MACed in a single buffer this is the simplest function to use.2453//2454//2455// SYMCRYPT_XXX_STATE2456//2457// The state encodes an ongoing MAC computation and allows incremental2458// computation of a MAC function.2459// At any point in time the state encodes a state that is equivalent to2460// the MAC computation of a data string X with the key specified during initialization of the state.2461// The SymCryptXxxInit() function initializes a state.2462// The SymCryptXxxAppend() function appends data to the data string X.2463// The SymCryptXxxResult() function returns the final MAC result.2464//2465// The state is an opaque type whose structure can change at will.2466// It should only be used for transient computations in a single executable2467// and not be stored or transferred to a different environment.2468//2469// Once initialized using SymCryptXxxInit, the state contains sensitive keying information.2470// The SymCryptXxxResult function wipes the sensitive information from the state.2471// Callers can also wipe the structure themselves if it is no longer needed.2472//2473// The state can be duplicated using the SymCryptXxxStateCopy function. This supports2474// applications that compute the MAC over a prefix and then duplicate the state to2475// compute the MAC using multiple different continuations.2476//2477//2478// VOID2479// SYMCRYPT_CALL2480// SymCryptXxxStateCopy(2481// _In_ PCSYMCRYPT_XXX_STATE pSrc,2482// _In_opt_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,2483// _Out_ PSYMCRYPT_XXX_STATE pDst );2484//2485// Create a copy of the pSrc state in pDst. If pExpandedKey is NULL, the pDst state2486// uses the same expanded key as the pSrc state did. If pExpandedKey is not NULL,2487// it must point to an expanded key that contains the same key material as the key2488// used by pSrc. (For example, a copy of the expanded key that pSrc uses.)2489//2490// VOID2491// SYMCRYPT_CALL2492// SymCryptXxxInit( _Out_ PSYMCRYPT_XXX_STATE pState,2493// _In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey);2494//2495// Initialize a SYMCRYPT_XXX_STATE for subsequent use with the provided key.2496//2497// This function can be called at any time and resets the state to correspond2498// to the empty data string with the newly specified key.2499// The SymCryptXxxAppend function appends data to the data string2500// encoded by the state.2501// The SymCryptXxxResult function finalizes the computation and2502// returns the actual MAC result.2503//2504// This function typically stores a pointer to the expanded key in the state.2505// The expanded key must remain unchanged in2506// memory until the SYMCRYPT_XXX_STATE structure is no longer used.2507//2508// After initialization the state contains sensitive keying materials, and should2509// be wiped when the state is no longer used. The SymCryptXxxResult() function2510// also wipes the state, so this is only a concern for aborted MAC computations.2511// Note that SymCryptXxxResult() does not wipe the expanded key; callers are always2512// responsible for wiping the expanded key.2513//2514//2515// VOID2516// SYMCRYPT_CALL2517// SymCryptXxxAppend( _Inout_ PSYMCRYPT_XXX_STATE pState,2518// _In_reads_( cbData ) PCBYTE pbData,2519// SIZE_T cbData );2520//2521// Provide more data to the ongoing MAC computation specified by the state.2522// The state must have been initialized by SymCryptXxxInit.2523// This function can be called multiple times on the same state2524// to append more data to the encoded data string.2525//2526// The SYMCRYPT_XXX_STATE structure contains the entire state of an ongoing2527// MAC computation. If you want to MAC some data and then continue with2528// multiple other strings you may create one or more copies of the state.2529// (The expanded key must remain unchanged in memory until all copies of the state2530// are no longer used.)2531//2532//2533// VOID2534// SYMCRYPT_CALL2535// SymCryptXxxResult(2536// _Inout_ PSYMCRYPT_XXX_STATE pState,2537// _Out_writes_( SYMCRYPT_XXX_RESULT_SIZE ) PBYTE pbResult );2538//2539// Returns the MAC result of the state.2540// If the state was newly initialized this returns the MAC of the empty string2541// using the key specified in the SymCryptXxxInit call.2542// If one or more SymCryptXxxAppend function calls were made on this state2543// it returns the MAC of the concatenation of all the data strings2544// passed to SymCryptXxxAppend using the specified key.2545//2546// The state is wiped to remove any traces of sensitive data.2547// To use the same state for another MAC computation you must call2548// SymCryptXxxInit again to re-initialize the state.2549// This behaviour is different from hash function states that are re-initialized for2550// use by the Result routine. This difference is by design; re-initializing a hash2551// state is a safe operation. Re-initializing a MAC state puts keying information2552// in the state, and callers would have to wipe the MAC state explicitly.2553//2554//2555// VOID2556// SYMCRYPT_CALL2557// SymCryptXxxSelftest(void);2558//2559// Perform a minimal self-test on the XXX algorithm.2560// This function is designed to be used for achieving FIPS 140-2 compliance or2561// to provide a simple self-test when an application starts.2562//2563// If an error is detected, a platform-specific fatal error action is taken.2564// Callers do not need to handle any error conditions.2565//2566//2567// We also have the Generic HMAC API where the hash function to be used in the HMAC2568// computation can be selected at runtime.2569//25702571typedef enum _SYMCRYPT_MAC_ID2572{2573SYMCRYPT_MAC_ID_NULL = 0,2574SYMCRYPT_MAC_ID_HMAC_MD5 = 1,2575SYMCRYPT_MAC_ID_HMAC_SHA1 = 2,2576SYMCRYPT_MAC_ID_HMAC_SHA224 = 3,2577SYMCRYPT_MAC_ID_HMAC_SHA256 = 4,2578SYMCRYPT_MAC_ID_HMAC_SHA384 = 5,2579SYMCRYPT_MAC_ID_HMAC_SHA512 = 6,2580SYMCRYPT_MAC_ID_HMAC_SHA512_224 = 7,2581SYMCRYPT_MAC_ID_HMAC_SHA512_256 = 8,2582SYMCRYPT_MAC_ID_HMAC_SHA3_224 = 9,2583SYMCRYPT_MAC_ID_HMAC_SHA3_256 = 10,2584SYMCRYPT_MAC_ID_HMAC_SHA3_384 = 11,2585SYMCRYPT_MAC_ID_HMAC_SHA3_512 = 12,2586SYMCRYPT_MAC_ID_AES_CMAC = 13,2587SYMCRYPT_MAC_ID_KMAC_128 = 14,2588SYMCRYPT_MAC_ID_KMAC_256 = 152589} SYMCRYPT_MAC_ID;25902591PCSYMCRYPT_MAC2592SYMCRYPT_CALL2593SymCryptGetMacAlgorithm( SYMCRYPT_MAC_ID macId );2594//2595// Returns a pointer to the MAC algorithm structure for the specified MAC ID.2596// Returns NULL if the MAC ID is invalid.2597//25982599//2600// Generic HMAC API with parametrized hash function2601//2602VOID2603SYMCRYPT_CALL2604SymCryptHmacStateCopy(2605_In_ PCSYMCRYPT_HMAC_STATE pSrc,2606_In_opt_ PCSYMCRYPT_HMAC_EXPANDED_KEY pExpandedKey,2607_Out_ PSYMCRYPT_HMAC_STATE pDst );26082609VOID2610SYMCRYPT_CALL2611SymCryptHmacKeyCopy(2612_In_ PCSYMCRYPT_HMAC_EXPANDED_KEY pSrc,2613_Out_ PSYMCRYPT_HMAC_EXPANDED_KEY pDst );26142615SYMCRYPT_ERROR2616SYMCRYPT_CALL2617SymCryptHmacExpandKey(2618_In_ PCSYMCRYPT_HASH pHash,2619_Out_ PSYMCRYPT_HMAC_EXPANDED_KEY pExpandedKey,2620_In_reads_opt_(cbKey) PCBYTE pbKey,2621SIZE_T cbKey );26222623SYMCRYPT_NOINLINE2624VOID2625SYMCRYPT_CALL2626SymCryptHmacInit(2627_Out_ PSYMCRYPT_HMAC_STATE pState,2628_In_ PCSYMCRYPT_HMAC_EXPANDED_KEY pExpandedKey );26292630VOID2631SYMCRYPT_CALL2632SymCryptHmacAppend(2633_Inout_ PSYMCRYPT_HMAC_STATE pState,2634_In_reads_( cbData ) PCBYTE pbData,2635SIZE_T cbData );26362637SYMCRYPT_NOINLINE2638VOID2639SYMCRYPT_CALL2640SymCryptHmacResult(2641_Inout_ PSYMCRYPT_HMAC_STATE pState,2642_Out_writes_( pState->pKey->pHash->resultSize ) PBYTE pbResult );26432644SYMCRYPT_NOINLINE2645VOID2646SYMCRYPT_CALL2647SymCryptHmac(2648_In_ PCSYMCRYPT_HMAC_EXPANDED_KEY pExpandedKey,2649_In_reads_( cbData ) PCBYTE pbData,2650SIZE_T cbData,2651_Out_writes_( pExpandedKey->pHash->resultSize ) PBYTE pbResult );265226532654////////////////////////////////////////////////////////////////////////////2655// HMAC-MD52656//2657//26582659#define SYMCRYPT_HMAC_MD5_RESULT_SIZE SYMCRYPT_MD5_RESULT_SIZE2660#define SYMCRYPT_HMAC_MD5_INPUT_BLOCK_SIZE SYMCRYPT_MD5_INPUT_BLOCK_SIZE26612662SYMCRYPT_ERROR2663SYMCRYPT_CALL2664SymCryptHmacMd5ExpandKey(2665_Out_ PSYMCRYPT_HMAC_MD5_EXPANDED_KEY pExpandedKey,2666_In_reads_opt_(cbKey) PCBYTE pbKey,2667SIZE_T cbKey );2668//2669// Supports all key lengths; never returns an error.2670//26712672VOID2673SYMCRYPT_CALL2674SymCryptHmacMd5KeyCopy(2675_In_ PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY pSrc,2676_Out_ PSYMCRYPT_HMAC_MD5_EXPANDED_KEY pDst );267726782679VOID2680SYMCRYPT_CALL2681SymCryptHmacMd5(2682_In_ PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY pExpandedKey,2683_In_reads_( cbData ) PCBYTE pbData,2684SIZE_T cbData,2685_Out_writes_( SYMCRYPT_HMAC_MD5_RESULT_SIZE ) PBYTE pbResult );26862687VOID2688SYMCRYPT_CALL2689SymCryptHmacMd5StateCopy(2690_In_ PCSYMCRYPT_HMAC_MD5_STATE pSrc,2691_In_opt_ PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY pExpandedKey,2692_Out_ PSYMCRYPT_HMAC_MD5_STATE pDst );26932694VOID2695SYMCRYPT_CALL2696SymCryptHmacMd5Init(2697_Out_ PSYMCRYPT_HMAC_MD5_STATE pState,2698_In_ PCSYMCRYPT_HMAC_MD5_EXPANDED_KEY pExpandedKey);26992700VOID2701SYMCRYPT_CALL2702SymCryptHmacMd5Append(2703_Inout_ PSYMCRYPT_HMAC_MD5_STATE pState,2704_In_reads_( cbData ) PCBYTE pbData,2705SIZE_T cbData );27062707VOID2708SYMCRYPT_CALL2709SymCryptHmacMd5Result(2710_Inout_ PSYMCRYPT_HMAC_MD5_STATE pState,2711_Out_writes_( SYMCRYPT_HMAC_MD5_RESULT_SIZE )PBYTE pbResult );27122713VOID2714SYMCRYPT_CALL2715SymCryptHmacMd5Selftest(void);27162717extern const PCSYMCRYPT_MAC SymCryptHmacMd5Algorithm;27182719////////////////////////////////////////////////////////////////////////////2720// HMAC-SHA-12721//2722//27232724#define SYMCRYPT_HMAC_SHA1_RESULT_SIZE SYMCRYPT_SHA1_RESULT_SIZE2725#define SYMCRYPT_HMAC_SHA1_INPUT_BLOCK_SIZE SYMCRYPT_SHA1_INPUT_BLOCK_SIZE27262727SYMCRYPT_ERROR2728SYMCRYPT_CALL2729SymCryptHmacSha1ExpandKey(2730_Out_ PSYMCRYPT_HMAC_SHA1_EXPANDED_KEY pExpandedKey,2731_In_reads_opt_(cbKey) PCBYTE pbKey,2732SIZE_T cbKey );2733//2734// Supports all key lengths; never returns an error.2735//27362737VOID2738SYMCRYPT_CALL2739SymCryptHmacSha1KeyCopy(2740_In_ PCSYMCRYPT_HMAC_SHA1_EXPANDED_KEY pSrc,2741_Out_ PSYMCRYPT_HMAC_SHA1_EXPANDED_KEY pDst );274227432744VOID2745SYMCRYPT_CALL2746SymCryptHmacSha1(2747_In_ PCSYMCRYPT_HMAC_SHA1_EXPANDED_KEY pExpandedKey,2748_In_reads_( cbData ) PCBYTE pbData,2749SIZE_T cbData,2750_Out_writes_( SYMCRYPT_HMAC_SHA1_RESULT_SIZE ) PBYTE pbResult );27512752VOID2753SYMCRYPT_CALL2754SymCryptHmacSha1StateCopy(2755_In_ PCSYMCRYPT_HMAC_SHA1_STATE pSrc,2756_In_opt_ PCSYMCRYPT_HMAC_SHA1_EXPANDED_KEY pExpandedKey,2757_Out_ PSYMCRYPT_HMAC_SHA1_STATE pDst );27582759VOID2760SYMCRYPT_CALL2761SymCryptHmacSha1Init(2762_Out_ PSYMCRYPT_HMAC_SHA1_STATE pState,2763_In_ PCSYMCRYPT_HMAC_SHA1_EXPANDED_KEY pExpandedKey);27642765VOID2766SYMCRYPT_CALL2767SymCryptHmacSha1Append(2768_Inout_ PSYMCRYPT_HMAC_SHA1_STATE pState,2769_In_reads_( cbData ) PCBYTE pbData,2770SIZE_T cbData );27712772VOID2773SYMCRYPT_CALL2774SymCryptHmacSha1Result(2775_Inout_ PSYMCRYPT_HMAC_SHA1_STATE pState,2776_Out_writes_( SYMCRYPT_HMAC_SHA1_RESULT_SIZE ) PBYTE pbResult );27772778VOID2779SYMCRYPT_CALL2780SymCryptHmacSha1Selftest(void);27812782extern const PCSYMCRYPT_MAC SymCryptHmacSha1Algorithm;27832784////////////////////////////////////////////////////////////////////////////2785// HMAC-SHA-2242786//2787// This implementation is meant for interoperability and is not recommended for use.2788//2789//27902791#define SYMCRYPT_HMAC_SHA224_RESULT_SIZE SYMCRYPT_SHA224_RESULT_SIZE2792#define SYMCRYPT_HMAC_SHA224_INPUT_BLOCK_SIZE SYMCRYPT_SHA224_INPUT_BLOCK_SIZE27932794SYMCRYPT_ERROR2795SYMCRYPT_CALL2796SymCryptHmacSha224ExpandKey(2797_Out_ PSYMCRYPT_HMAC_SHA224_EXPANDED_KEY pExpandedKey,2798_In_reads_opt_(cbKey) PCBYTE pbKey,2799SIZE_T cbKey );2800//2801// Supports all key lengths; never returns an error.2802//28032804VOID2805SYMCRYPT_CALL2806SymCryptHmacSha224KeyCopy(2807_In_ PCSYMCRYPT_HMAC_SHA224_EXPANDED_KEY pSrc,2808_Out_ PSYMCRYPT_HMAC_SHA224_EXPANDED_KEY pDst );28092810VOID2811SYMCRYPT_CALL2812SymCryptHmacSha224(2813_In_ PCSYMCRYPT_HMAC_SHA224_EXPANDED_KEY pExpandedKey,2814_In_reads_( cbData ) PCBYTE pbData,2815SIZE_T cbData,2816_Out_writes_( SYMCRYPT_HMAC_SHA224_RESULT_SIZE )PBYTE pbResult );28172818VOID2819SYMCRYPT_CALL2820SymCryptHmacSha224StateCopy(2821_In_ PCSYMCRYPT_HMAC_SHA224_STATE pSrc,2822_In_opt_ PCSYMCRYPT_HMAC_SHA224_EXPANDED_KEY pExpandedKey,2823_Out_ PSYMCRYPT_HMAC_SHA224_STATE pDst );28242825VOID2826SYMCRYPT_CALL2827SymCryptHmacSha224Init(2828_Out_ PSYMCRYPT_HMAC_SHA224_STATE pState,2829_In_ PCSYMCRYPT_HMAC_SHA224_EXPANDED_KEY pExpandedKey);28302831VOID2832SYMCRYPT_CALL2833SymCryptHmacSha224Append(2834_Inout_ PSYMCRYPT_HMAC_SHA224_STATE pState,2835_In_reads_( cbData ) PCBYTE pbData,2836SIZE_T cbData );28372838VOID2839SYMCRYPT_CALL2840SymCryptHmacSha224Result(2841_Inout_ PSYMCRYPT_HMAC_SHA224_STATE pState,2842_Out_writes_( SYMCRYPT_HMAC_SHA224_RESULT_SIZE )PBYTE pbResult );28432844VOID2845SYMCRYPT_CALL2846SymCryptHmacSha224Selftest(void);28472848extern const PCSYMCRYPT_MAC SymCryptHmacSha224Algorithm;28492850////////////////////////////////////////////////////////////////////////////2851// HMAC-SHA-2562852//2853//28542855#define SYMCRYPT_HMAC_SHA256_RESULT_SIZE SYMCRYPT_SHA256_RESULT_SIZE2856#define SYMCRYPT_HMAC_SHA256_INPUT_BLOCK_SIZE SYMCRYPT_SHA256_INPUT_BLOCK_SIZE28572858SYMCRYPT_ERROR2859SYMCRYPT_CALL2860SymCryptHmacSha256ExpandKey(2861_Out_ PSYMCRYPT_HMAC_SHA256_EXPANDED_KEY pExpandedKey,2862_In_reads_opt_(cbKey) PCBYTE pbKey,2863SIZE_T cbKey );2864//2865// Supports all key lengths; never returns an error.2866//28672868VOID2869SYMCRYPT_CALL2870SymCryptHmacSha256KeyCopy(2871_In_ PCSYMCRYPT_HMAC_SHA256_EXPANDED_KEY pSrc,2872_Out_ PSYMCRYPT_HMAC_SHA256_EXPANDED_KEY pDst );28732874VOID2875SYMCRYPT_CALL2876SymCryptHmacSha256(2877_In_ PCSYMCRYPT_HMAC_SHA256_EXPANDED_KEY pExpandedKey,2878_In_reads_( cbData ) PCBYTE pbData,2879SIZE_T cbData,2880_Out_writes_( SYMCRYPT_HMAC_SHA256_RESULT_SIZE )PBYTE pbResult );28812882VOID2883SYMCRYPT_CALL2884SymCryptHmacSha256StateCopy(2885_In_ PCSYMCRYPT_HMAC_SHA256_STATE pSrc,2886_In_opt_ PCSYMCRYPT_HMAC_SHA256_EXPANDED_KEY pExpandedKey,2887_Out_ PSYMCRYPT_HMAC_SHA256_STATE pDst );28882889VOID2890SYMCRYPT_CALL2891SymCryptHmacSha256Init(2892_Out_ PSYMCRYPT_HMAC_SHA256_STATE pState,2893_In_ PCSYMCRYPT_HMAC_SHA256_EXPANDED_KEY pExpandedKey);28942895VOID2896SYMCRYPT_CALL2897SymCryptHmacSha256Append(2898_Inout_ PSYMCRYPT_HMAC_SHA256_STATE pState,2899_In_reads_( cbData ) PCBYTE pbData,2900SIZE_T cbData );29012902VOID2903SYMCRYPT_CALL2904SymCryptHmacSha256Result(2905_Inout_ PSYMCRYPT_HMAC_SHA256_STATE pState,2906_Out_writes_( SYMCRYPT_HMAC_SHA256_RESULT_SIZE )PBYTE pbResult );29072908VOID2909SYMCRYPT_CALL2910SymCryptHmacSha256Selftest(void);29112912extern const PCSYMCRYPT_MAC SymCryptHmacSha256Algorithm;29132914////////////////////////////////////////////////////////////////////////////2915// HMAC-SHA-3842916//2917//29182919#define SYMCRYPT_HMAC_SHA384_RESULT_SIZE SYMCRYPT_SHA384_RESULT_SIZE2920#define SYMCRYPT_HMAC_SHA384_INPUT_BLOCK_SIZE SYMCRYPT_SHA384_INPUT_BLOCK_SIZE29212922SYMCRYPT_ERROR2923SYMCRYPT_CALL2924SymCryptHmacSha384ExpandKey(2925_Out_ PSYMCRYPT_HMAC_SHA384_EXPANDED_KEY pExpandedKey,2926_In_reads_opt_(cbKey) PCBYTE pbKey,2927SIZE_T cbKey );2928//2929// Supports all key lengths; never returns an error.2930//29312932VOID2933SYMCRYPT_CALL2934SymCryptHmacSha384KeyCopy(2935_In_ PCSYMCRYPT_HMAC_SHA384_EXPANDED_KEY pSrc,2936_Out_ PSYMCRYPT_HMAC_SHA384_EXPANDED_KEY pDst );29372938VOID2939SYMCRYPT_CALL2940SymCryptHmacSha384(2941_In_ PCSYMCRYPT_HMAC_SHA384_EXPANDED_KEY pExpandedKey,2942_In_reads_( cbData ) PCBYTE pbData,2943SIZE_T cbData,2944_Out_writes_( SYMCRYPT_HMAC_SHA384_RESULT_SIZE )PBYTE pbResult );29452946VOID2947SYMCRYPT_CALL2948SymCryptHmacSha384StateCopy(2949_In_ PCSYMCRYPT_HMAC_SHA384_STATE pSrc,2950_In_opt_ PCSYMCRYPT_HMAC_SHA384_EXPANDED_KEY pExpandedKey,2951_Out_ PSYMCRYPT_HMAC_SHA384_STATE pDst );29522953VOID2954SYMCRYPT_CALL2955SymCryptHmacSha384Init(2956_Out_ PSYMCRYPT_HMAC_SHA384_STATE pState,2957_In_ PCSYMCRYPT_HMAC_SHA384_EXPANDED_KEY pExpandedKey);29582959VOID2960SYMCRYPT_CALL2961SymCryptHmacSha384Append(2962_Inout_ PSYMCRYPT_HMAC_SHA384_STATE pState,2963_In_reads_( cbData ) PCBYTE pbData,2964SIZE_T cbData );29652966VOID2967SYMCRYPT_CALL2968SymCryptHmacSha384Result(2969_Inout_ PSYMCRYPT_HMAC_SHA384_STATE pState,2970_Out_writes_( SYMCRYPT_HMAC_SHA384_RESULT_SIZE )PBYTE pbResult );29712972VOID2973SYMCRYPT_CALL2974SymCryptHmacSha384Selftest(void);29752976extern const PCSYMCRYPT_MAC SymCryptHmacSha384Algorithm;29772978////////////////////////////////////////////////////////////////////////////2979// HMAC-SHA-5122980//2981//29822983#define SYMCRYPT_HMAC_SHA512_RESULT_SIZE SYMCRYPT_SHA512_RESULT_SIZE2984#define SYMCRYPT_HMAC_SHA512_INPUT_BLOCK_SIZE SYMCRYPT_SHA512_INPUT_BLOCK_SIZE29852986SYMCRYPT_ERROR2987SYMCRYPT_CALL2988SymCryptHmacSha512ExpandKey(2989_Out_ PSYMCRYPT_HMAC_SHA512_EXPANDED_KEY pExpandedKey,2990_In_reads_opt_(cbKey) PCBYTE pbKey,2991SIZE_T cbKey );2992//2993// Supports all key lengths; never returns an error.2994//29952996VOID2997SYMCRYPT_CALL2998SymCryptHmacSha512KeyCopy(2999_In_ PCSYMCRYPT_HMAC_SHA512_EXPANDED_KEY pSrc,3000_Out_ PSYMCRYPT_HMAC_SHA512_EXPANDED_KEY pDst );30013002VOID3003SYMCRYPT_CALL3004SymCryptHmacSha512(3005_In_ PCSYMCRYPT_HMAC_SHA512_EXPANDED_KEY pExpandedKey,3006_In_reads_( cbData ) PCBYTE pbData,3007SIZE_T cbData,3008_Out_writes_( SYMCRYPT_HMAC_SHA512_RESULT_SIZE )PBYTE pbResult );30093010VOID3011SYMCRYPT_CALL3012SymCryptHmacSha512StateCopy(3013_In_ PCSYMCRYPT_HMAC_SHA512_STATE pSrc,3014_In_opt_ PCSYMCRYPT_HMAC_SHA512_EXPANDED_KEY pExpandedKey,3015_Out_ PSYMCRYPT_HMAC_SHA512_STATE pDst );30163017VOID3018SYMCRYPT_CALL3019SymCryptHmacSha512Init(3020_Out_ PSYMCRYPT_HMAC_SHA512_STATE pState,3021_In_ PCSYMCRYPT_HMAC_SHA512_EXPANDED_KEY pExpandedKey);30223023VOID3024SYMCRYPT_CALL3025SymCryptHmacSha512Append(3026_Inout_ PSYMCRYPT_HMAC_SHA512_STATE pState,3027_In_reads_( cbData ) PCBYTE pbData,3028SIZE_T cbData );30293030VOID3031SYMCRYPT_CALL3032SymCryptHmacSha512Result(3033_Inout_ PSYMCRYPT_HMAC_SHA512_STATE pState,3034_Out_writes_( SYMCRYPT_HMAC_SHA512_RESULT_SIZE )PBYTE pbResult );30353036VOID3037SYMCRYPT_CALL3038SymCryptHmacSha512Selftest(void);30393040extern const PCSYMCRYPT_MAC SymCryptHmacSha512Algorithm;30413042////////////////////////////////////////////////////////////////////////////3043// HMAC-SHA-512_2243044//3045// This implementation is meant for interoperability and is not recommended for use.3046//3047//30483049#define SYMCRYPT_HMAC_SHA512_224_RESULT_SIZE SYMCRYPT_SHA512_224_RESULT_SIZE3050#define SYMCRYPT_HMAC_SHA512_224_INPUT_BLOCK_SIZE SYMCRYPT_SHA512_224_INPUT_BLOCK_SIZE30513052SYMCRYPT_ERROR3053SYMCRYPT_CALL3054SymCryptHmacSha512_224ExpandKey(3055_Out_ PSYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY pExpandedKey,3056_In_reads_opt_(cbKey) PCBYTE pbKey,3057SIZE_T cbKey );3058//3059// Supports all key lengths; never returns an error.3060//30613062VOID3063SYMCRYPT_CALL3064SymCryptHmacSha512_224KeyCopy(3065_In_ PCSYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY pSrc,3066_Out_ PSYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY pDst );30673068VOID3069SYMCRYPT_CALL3070SymCryptHmacSha512_224(3071_In_ PCSYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY pExpandedKey,3072_In_reads_( cbData ) PCBYTE pbData,3073SIZE_T cbData,3074_Out_writes_( SYMCRYPT_HMAC_SHA512_224_RESULT_SIZE ) PBYTE pbResult );30753076VOID3077SYMCRYPT_CALL3078SymCryptHmacSha512_224StateCopy(3079_In_ PCSYMCRYPT_HMAC_SHA512_224_STATE pSrc,3080_In_opt_ PCSYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY pExpandedKey,3081_Out_ PSYMCRYPT_HMAC_SHA512_224_STATE pDst );30823083VOID3084SYMCRYPT_CALL3085SymCryptHmacSha512_224Init(3086_Out_ PSYMCRYPT_HMAC_SHA512_224_STATE pState,3087_In_ PCSYMCRYPT_HMAC_SHA512_224_EXPANDED_KEY pExpandedKey);30883089VOID3090SYMCRYPT_CALL3091SymCryptHmacSha512_224Append(3092_Inout_ PSYMCRYPT_HMAC_SHA512_224_STATE pState,3093_In_reads_( cbData ) PCBYTE pbData,3094SIZE_T cbData );30953096VOID3097SYMCRYPT_CALL3098SymCryptHmacSha512_224Result(3099_Inout_ PSYMCRYPT_HMAC_SHA512_224_STATE pState,3100_Out_writes_( SYMCRYPT_HMAC_SHA512_224_RESULT_SIZE ) PBYTE pbResult );31013102VOID3103SYMCRYPT_CALL3104SymCryptHmacSha512_224Selftest(void);31053106extern const PCSYMCRYPT_MAC SymCryptHmacSha512_224Algorithm;31073108////////////////////////////////////////////////////////////////////////////3109// HMAC-SHA-512_2563110//3111// This implementation is meant for interoperability and is not recommended for use.3112//3113//31143115#define SYMCRYPT_HMAC_SHA512_256_RESULT_SIZE SYMCRYPT_SHA512_256_RESULT_SIZE3116#define SYMCRYPT_HMAC_SHA512_256_INPUT_BLOCK_SIZE SYMCRYPT_SHA512_256_INPUT_BLOCK_SIZE31173118SYMCRYPT_ERROR3119SYMCRYPT_CALL3120SymCryptHmacSha512_256ExpandKey(3121_Out_ PSYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY pExpandedKey,3122_In_reads_opt_(cbKey) PCBYTE pbKey,3123SIZE_T cbKey );3124//3125// Supports all key lengths; never returns an error.3126//31273128VOID3129SYMCRYPT_CALL3130SymCryptHmacSha512_256KeyCopy(3131_In_ PCSYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY pSrc,3132_Out_ PSYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY pDst );31333134VOID3135SYMCRYPT_CALL3136SymCryptHmacSha512_256(3137_In_ PCSYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY pExpandedKey,3138_In_reads_( cbData ) PCBYTE pbData,3139SIZE_T cbData,3140_Out_writes_( SYMCRYPT_HMAC_SHA512_256_RESULT_SIZE ) PBYTE pbResult );31413142VOID3143SYMCRYPT_CALL3144SymCryptHmacSha512_256StateCopy(3145_In_ PCSYMCRYPT_HMAC_SHA512_256_STATE pSrc,3146_In_opt_ PCSYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY pExpandedKey,3147_Out_ PSYMCRYPT_HMAC_SHA512_256_STATE pDst );31483149VOID3150SYMCRYPT_CALL3151SymCryptHmacSha512_256Init(3152_Out_ PSYMCRYPT_HMAC_SHA512_256_STATE pState,3153_In_ PCSYMCRYPT_HMAC_SHA512_256_EXPANDED_KEY pExpandedKey);31543155VOID3156SYMCRYPT_CALL3157SymCryptHmacSha512_256Append(3158_Inout_ PSYMCRYPT_HMAC_SHA512_256_STATE pState,3159_In_reads_( cbData ) PCBYTE pbData,3160SIZE_T cbData );31613162VOID3163SYMCRYPT_CALL3164SymCryptHmacSha512_256Result(3165_Inout_ PSYMCRYPT_HMAC_SHA512_256_STATE pState,3166_Out_writes_( SYMCRYPT_HMAC_SHA512_256_RESULT_SIZE ) PBYTE pbResult );31673168VOID3169SYMCRYPT_CALL3170SymCryptHmacSha512_256Selftest(void);31713172extern const PCSYMCRYPT_MAC SymCryptHmacSha512_256Algorithm;31733174////////////////////////////////////////////////////////////////////////////3175// HMAC-SHA3-2243176//3177// This implementation is meant for interoperability and is not recommended for use.3178//3179//31803181#define SYMCRYPT_HMAC_SHA3_224_RESULT_SIZE SYMCRYPT_SHA3_224_RESULT_SIZE3182#define SYMCRYPT_HMAC_SHA3_224_INPUT_BLOCK_SIZE SYMCRYPT_SHA3_224_INPUT_BLOCK_SIZE31833184SYMCRYPT_ERROR3185SYMCRYPT_CALL3186SymCryptHmacSha3_224ExpandKey(3187_Out_ PSYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY pExpandedKey,3188_In_reads_opt_(cbKey) PCBYTE pbKey,3189SIZE_T cbKey );3190//3191// Supports all key lengths; never returns an error.3192//31933194VOID3195SYMCRYPT_CALL3196SymCryptHmacSha3_224KeyCopy(3197_In_ PCSYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY pSrc,3198_Out_ PSYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY pDst );31993200VOID3201SYMCRYPT_CALL3202SymCryptHmacSha3_224(3203_In_ PCSYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY pExpandedKey,3204_In_reads_( cbData ) PCBYTE pbData,3205SIZE_T cbData,3206_Out_writes_( SYMCRYPT_HMAC_SHA3_224_RESULT_SIZE ) PBYTE pbResult );32073208VOID3209SYMCRYPT_CALL3210SymCryptHmacSha3_224StateCopy(3211_In_ PCSYMCRYPT_HMAC_SHA3_224_STATE pSrc,3212_In_opt_ PCSYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY pExpandedKey,3213_Out_ PSYMCRYPT_HMAC_SHA3_224_STATE pDst );32143215VOID3216SYMCRYPT_CALL3217SymCryptHmacSha3_224Init(3218_Out_ PSYMCRYPT_HMAC_SHA3_224_STATE pState,3219_In_ PCSYMCRYPT_HMAC_SHA3_224_EXPANDED_KEY pExpandedKey);32203221VOID3222SYMCRYPT_CALL3223SymCryptHmacSha3_224Append(3224_Inout_ PSYMCRYPT_HMAC_SHA3_224_STATE pState,3225_In_reads_( cbData ) PCBYTE pbData,3226SIZE_T cbData );32273228VOID3229SYMCRYPT_CALL3230SymCryptHmacSha3_224Result(3231_Inout_ PSYMCRYPT_HMAC_SHA3_224_STATE pState,3232_Out_writes_( SYMCRYPT_HMAC_SHA3_224_RESULT_SIZE ) PBYTE pbResult );32333234VOID3235SYMCRYPT_CALL3236SymCryptHmacSha3_224Selftest(void);32373238extern const PCSYMCRYPT_MAC SymCryptHmacSha3_224Algorithm;32393240////////////////////////////////////////////////////////////////////////////3241// HMAC-SHA3-2563242//3243//32443245#define SYMCRYPT_HMAC_SHA3_256_RESULT_SIZE SYMCRYPT_SHA3_256_RESULT_SIZE3246#define SYMCRYPT_HMAC_SHA3_256_INPUT_BLOCK_SIZE SYMCRYPT_SHA3_256_INPUT_BLOCK_SIZE32473248SYMCRYPT_ERROR3249SYMCRYPT_CALL3250SymCryptHmacSha3_256ExpandKey(3251_Out_ PSYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY pExpandedKey,3252_In_reads_opt_(cbKey) PCBYTE pbKey,3253SIZE_T cbKey );3254//3255// Supports all key lengths; never returns an error.3256//32573258VOID3259SYMCRYPT_CALL3260SymCryptHmacSha3_256KeyCopy(3261_In_ PCSYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY pSrc,3262_Out_ PSYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY pDst );32633264VOID3265SYMCRYPT_CALL3266SymCryptHmacSha3_256(3267_In_ PCSYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY pExpandedKey,3268_In_reads_( cbData ) PCBYTE pbData,3269SIZE_T cbData,3270_Out_writes_( SYMCRYPT_HMAC_SHA3_256_RESULT_SIZE ) PBYTE pbResult );32713272VOID3273SYMCRYPT_CALL3274SymCryptHmacSha3_256StateCopy(3275_In_ PCSYMCRYPT_HMAC_SHA3_256_STATE pSrc,3276_In_opt_ PCSYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY pExpandedKey,3277_Out_ PSYMCRYPT_HMAC_SHA3_256_STATE pDst );32783279VOID3280SYMCRYPT_CALL3281SymCryptHmacSha3_256Init(3282_Out_ PSYMCRYPT_HMAC_SHA3_256_STATE pState,3283_In_ PCSYMCRYPT_HMAC_SHA3_256_EXPANDED_KEY pExpandedKey);32843285VOID3286SYMCRYPT_CALL3287SymCryptHmacSha3_256Append(3288_Inout_ PSYMCRYPT_HMAC_SHA3_256_STATE pState,3289_In_reads_( cbData ) PCBYTE pbData,3290SIZE_T cbData );32913292VOID3293SYMCRYPT_CALL3294SymCryptHmacSha3_256Result(3295_Inout_ PSYMCRYPT_HMAC_SHA3_256_STATE pState,3296_Out_writes_( SYMCRYPT_HMAC_SHA3_256_RESULT_SIZE ) PBYTE pbResult );32973298VOID3299SYMCRYPT_CALL3300SymCryptHmacSha3_256Selftest(void);33013302extern const PCSYMCRYPT_MAC SymCryptHmacSha3_256Algorithm;33033304////////////////////////////////////////////////////////////////////////////3305// HMAC-SHA3-3843306//3307//33083309#define SYMCRYPT_HMAC_SHA3_384_RESULT_SIZE SYMCRYPT_SHA3_384_RESULT_SIZE3310#define SYMCRYPT_HMAC_SHA3_384_INPUT_BLOCK_SIZE SYMCRYPT_SHA3_384_INPUT_BLOCK_SIZE33113312SYMCRYPT_ERROR3313SYMCRYPT_CALL3314SymCryptHmacSha3_384ExpandKey(3315_Out_ PSYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY pExpandedKey,3316_In_reads_opt_(cbKey) PCBYTE pbKey,3317SIZE_T cbKey );3318//3319// Supports all key lengths; never returns an error.3320//33213322VOID3323SYMCRYPT_CALL3324SymCryptHmacSha3_384KeyCopy(3325_In_ PCSYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY pSrc,3326_Out_ PSYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY pDst );33273328VOID3329SYMCRYPT_CALL3330SymCryptHmacSha3_384(3331_In_ PCSYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY pExpandedKey,3332_In_reads_( cbData ) PCBYTE pbData,3333SIZE_T cbData,3334_Out_writes_( SYMCRYPT_HMAC_SHA3_384_RESULT_SIZE ) PBYTE pbResult );33353336VOID3337SYMCRYPT_CALL3338SymCryptHmacSha3_384StateCopy(3339_In_ PCSYMCRYPT_HMAC_SHA3_384_STATE pSrc,3340_In_opt_ PCSYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY pExpandedKey,3341_Out_ PSYMCRYPT_HMAC_SHA3_384_STATE pDst );33423343VOID3344SYMCRYPT_CALL3345SymCryptHmacSha3_384Init(3346_Out_ PSYMCRYPT_HMAC_SHA3_384_STATE pState,3347_In_ PCSYMCRYPT_HMAC_SHA3_384_EXPANDED_KEY pExpandedKey);33483349VOID3350SYMCRYPT_CALL3351SymCryptHmacSha3_384Append(3352_Inout_ PSYMCRYPT_HMAC_SHA3_384_STATE pState,3353_In_reads_( cbData ) PCBYTE pbData,3354SIZE_T cbData );33553356VOID3357SYMCRYPT_CALL3358SymCryptHmacSha3_384Result(3359_Inout_ PSYMCRYPT_HMAC_SHA3_384_STATE pState,3360_Out_writes_( SYMCRYPT_HMAC_SHA3_384_RESULT_SIZE ) PBYTE pbResult );33613362VOID3363SYMCRYPT_CALL3364SymCryptHmacSha3_384Selftest(void);33653366extern const PCSYMCRYPT_MAC SymCryptHmacSha3_384Algorithm;33673368////////////////////////////////////////////////////////////////////////////3369// HMAC-SHA3-5123370//3371//33723373#define SYMCRYPT_HMAC_SHA3_512_RESULT_SIZE SYMCRYPT_SHA3_512_RESULT_SIZE3374#define SYMCRYPT_HMAC_SHA3_512_INPUT_BLOCK_SIZE SYMCRYPT_SHA3_512_INPUT_BLOCK_SIZE33753376SYMCRYPT_ERROR3377SYMCRYPT_CALL3378SymCryptHmacSha3_512ExpandKey(3379_Out_ PSYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY pExpandedKey,3380_In_reads_opt_(cbKey) PCBYTE pbKey,3381SIZE_T cbKey );3382//3383// Supports all key lengths; never returns an error.3384//33853386VOID3387SYMCRYPT_CALL3388SymCryptHmacSha3_512KeyCopy(3389_In_ PCSYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY pSrc,3390_Out_ PSYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY pDst );33913392VOID3393SYMCRYPT_CALL3394SymCryptHmacSha3_512(3395_In_ PCSYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY pExpandedKey,3396_In_reads_( cbData ) PCBYTE pbData,3397SIZE_T cbData,3398_Out_writes_( SYMCRYPT_HMAC_SHA3_512_RESULT_SIZE ) PBYTE pbResult );33993400VOID3401SYMCRYPT_CALL3402SymCryptHmacSha3_512StateCopy(3403_In_ PCSYMCRYPT_HMAC_SHA3_512_STATE pSrc,3404_In_opt_ PCSYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY pExpandedKey,3405_Out_ PSYMCRYPT_HMAC_SHA3_512_STATE pDst );34063407VOID3408SYMCRYPT_CALL3409SymCryptHmacSha3_512Init(3410_Out_ PSYMCRYPT_HMAC_SHA3_512_STATE pState,3411_In_ PCSYMCRYPT_HMAC_SHA3_512_EXPANDED_KEY pExpandedKey);34123413VOID3414SYMCRYPT_CALL3415SymCryptHmacSha3_512Append(3416_Inout_ PSYMCRYPT_HMAC_SHA3_512_STATE pState,3417_In_reads_( cbData ) PCBYTE pbData,3418SIZE_T cbData );34193420VOID3421SYMCRYPT_CALL3422SymCryptHmacSha3_512Result(3423_Inout_ PSYMCRYPT_HMAC_SHA3_512_STATE pState,3424_Out_writes_( SYMCRYPT_HMAC_SHA3_512_RESULT_SIZE ) PBYTE pbResult );34253426VOID3427SYMCRYPT_CALL3428SymCryptHmacSha3_512Selftest(void);34293430extern const PCSYMCRYPT_MAC SymCryptHmacSha3_512Algorithm;343134323433////////////////////////////////////////////////////////////////////////////3434// AES-CMAC3435//3436// This is the AES-CMAC algorithm per SP 800-38B & RFC 4493.3437// It is also known as AES-OMAC1.3438//34393440#define SYMCRYPT_AES_CMAC_RESULT_SIZE (16)3441#define SYMCRYPT_AES_CMAC_INPUT_BLOCK_SIZE (16)34423443SYMCRYPT_ERROR3444SYMCRYPT_CALL3445SymCryptAesCmacExpandKey(3446_Out_ PSYMCRYPT_AES_CMAC_EXPANDED_KEY pExpandedKey,3447_In_reads_(cbKey) PCBYTE pbKey,3448SIZE_T cbKey );3449//3450// Key size must be a valid AES key (16, 24, or 32 bytes)3451//34523453VOID3454SYMCRYPT_CALL3455SymCryptAesCmacKeyCopy(3456_In_ PCSYMCRYPT_AES_CMAC_EXPANDED_KEY pSrc,3457_Out_ PSYMCRYPT_AES_CMAC_EXPANDED_KEY pDst );34583459VOID3460SYMCRYPT_CALL3461SymCryptAesCmac(3462_In_ PSYMCRYPT_AES_CMAC_EXPANDED_KEY pExpandedKey,3463_In_reads_( cbData ) PCBYTE pbData,3464SIZE_T cbData,3465_Out_writes_( SYMCRYPT_AES_CMAC_RESULT_SIZE ) PBYTE pbResult );34663467VOID3468SYMCRYPT_CALL3469SymCryptAesCmacStateCopy(3470_In_ PCSYMCRYPT_AES_CMAC_STATE pSrc,3471_In_opt_ PCSYMCRYPT_AES_CMAC_EXPANDED_KEY pExpandedKey,3472_Out_ PSYMCRYPT_AES_CMAC_STATE pDst );34733474VOID3475SYMCRYPT_CALL3476SymCryptAesCmacInit(3477_Out_ PSYMCRYPT_AES_CMAC_STATE pState,3478_In_ PCSYMCRYPT_AES_CMAC_EXPANDED_KEY pExpandedKey);34793480VOID3481SYMCRYPT_CALL3482SymCryptAesCmacAppend(3483_Inout_ PSYMCRYPT_AES_CMAC_STATE pState,3484_In_reads_( cbData ) PCBYTE pbData,3485SIZE_T cbData );34863487VOID3488SYMCRYPT_CALL3489SymCryptAesCmacResult(3490_Inout_ PSYMCRYPT_AES_CMAC_STATE pState,3491_Out_writes_( SYMCRYPT_AES_CMAC_RESULT_SIZE ) PBYTE pbResult );34923493VOID3494SYMCRYPT_CALL3495SymCryptAesCmacSelftest(void);34963497extern const PCSYMCRYPT_MAC SymCryptAesCmacAlgorithm;34983499////////////////////////////////////////////////////////////////////////////3500// KMAC3501//3502// Keccak Message Authentication Code (KMAC) is specified in NIST SP 800-1853503// and has two variants; KMAC128 and KMAC256, using cSHAKE128 and cSHAKE2563504// as the underlying functions, respectively.3505//3506// KMAC128(K, X, L, S) = cSHAKE128(bytepad(encode_string(K), 168) || X || right_encode(L), L, "KMAC", S)3507// KMAC256(K, X, L, S) = cSHAKE256(bytepad(encode_string(K), 136) || X || right_encode(L), L, "KMAC", S)3508//3509// KMAC accepts a variable-size key. There's no restriction on the size of the key.3510//3511// KMAC differs from other MAC algorithms in SymCrypt by having two additional input3512// parameters; a customization string and the length of the output. Output generated3513// by KMAC also depends on the specified output length, i.e., outputs generated from3514// two KMAC calls with the same key, message, customization string, but different output3515// lengths will be unrelated/uncorrelated. This differs from SHAKE and cSHAKE where an3516// output of size N bytes from the algorithm is a prefix of the output of size M bytes3517// where N < M, when the inputs are the same.3518//3519// KMAC works in two modes; fixed-length mode and XOF mode. XOF variants are named KMACXOF1283520// and KMACXOF256. SymCrypt does not provide a separate KMACXOF API but supports them via3521// the KMAC interface.3522//3523// KMACXOF128(K, X, L, S) = cSHAKE128(bytepad(encode_string(K), 168) || X || right_encode(0), L, "KMAC", S)3524// KMACXOF256(K, X, L, S) = cSHAKE256(bytepad(encode_string(K), 136) || X || right_encode(0), L, "KMAC", S)3525//3526// KMAC output generation mode is determined by the output length parameter3527// L in SP 800-185; if it is non-zero then KMAC works in fixed-length mode, otherwise (i.e., L=0)3528// it works in XOF mode.3529// - Fixed-length mode generates result with SymCryptKmacXxxResult or SymCryptKmacXxxResultEx.3530// These functions wipe the state after generating output, thus can only be used3531// once per initialized state. The result size is SYMCRYPT_KMAC_XXX_RESULT3532// for SymCryptKmacXxxResult and specified by the caller for SymCryptKmacXxxResultEx.3533// - XOF mode can produce arbitrary length output. SymCryptKmacXxxExtract function puts KMAC3534// state into XOF mode and all the successive calls that generate output from the KMAC state will be3535// from the XOF mode. SymCryptKmacXxxResult and SymCryptKmacXxxResultEx functions3536// will also generate output in XOF mode IF they are called after a SymCryptKmacXxxExtract3537// function with bWipe=FALSE (so that the state remains in XOF mode). Note that3538// SymCryptKmacXxxResult and SymCryptKmacXxxResultEx functions wipe the state afterwards,3539// thus KMAC state can only be used to generate output in XOF mode once with these two functions.3540//3541// SYMCRYPT_KMACXXX_RESULT_SIZE3542//3543// Default result size when KMAC is used with the existing MAC interface.3544// Equals to twice the SYMCRYPT_KMACXXX_KEY_SIZE.3545//3546// SYMCRYPT_ERROR3547// SYMCRYPT_CALL3548// SymCryptKmacXxxExpandKey(3549// _Out_ PSYMCRYPT_KMACXXX_EXPANDED_KEY pExpandedKey,3550// _In_reads_bytes_( cbKey ) PCBYTE pbKey,3551// SIZE_T cbKey);3552//3553// Performs key expansion with empty customization string.3554// There's no restriction on the size of the key.3555//3556// SYMCRYPT_ERROR3557// SYMCRYPT_CALL3558// SymCryptKmacXxxExpandKeyEx(3559// _Out_ PSYMCRYPT_KMAXXX_EXPANDED_KEY pExpandedKey,3560// _In_reads_bytes_( cbKey ) PCBYTE pbKey,3561// SIZE_T cbKey,3562// _In_reads_bytes_( cbCustomizationString ) PCBYTE pbCustomizationString,3563// SIZE_T cbCustomizationString);3564//3565// Performs key expansion for the provided key and customization string.3566// There's no restriction on the size of the key.3567//3568// VOID3569// SYMCRYPT_CALL3570// SymCryptKmacXxx(3571// _In_ PCSYMCRYPT_KMACXXX_EXPANDED_KEY pExpandedKey,3572// _In_reads_bytes_( cbInput ) PCBYTE pbInput,3573// SIZE_T cbInput,3574// _Out_writes_bytes_( SYMCRYPT_KMACXXX_RESULT_SIZE ) PBYTE pbResult);3575//3576// Single-call KMAC computation for the given input producing default result3577// size SYMCRYPT_KMACXXX_RESULT_SIZE.3578//3579// pExpandedKey must be initialized before the call. This function is equivalent3580// to SymCryptKmacXxxEx with output size set to SYMCRYPT_KMACXXX_RESULT_SIZE.3581// If a result size different than the default value is desired, SymCryptKmacXxxEx3582// must be called.3583//3584// VOID3585// SYMCRYPT_CALL3586// SymCryptKmacXxxEx(3587// _In_ PCSYMCRYPT_KMACXXX_EXPANDED_KEY pExpandedKey,3588// _In_reads_bytes_( cbInput ) PCBYTE pbInput,3589// SIZE_T cbInput,3590// _Out_writes_bytes_( cbResult ) PBYTE pbResult,3591// SIZE_T cbResult);3592//3593// Single-call KMAC computation for the given input producing cbResult bytes result.3594// pExpandedKey must be initialized before the call.3595//3596// VOID3597// SYMCRYPT_CALL3598// SymCryptKmacXxxInit(3599// _Out_ PSYMCRYPT_KMACXXX_STATE pState,3600// _In_ PCSYMCRYPT_KMACXXX_EXPANDED_KEY pExpandedKey);3601//3602// Initializes KMAC state for appending data for the provided key. Expanded3603// key must be generated prior to this call.3604//3605// VOID3606// SYMCRYPT_CALL3607// SymCryptKmacXxxAppend(3608// _Inout_ PSYMCRYPT_KMACXXX_STATE pState,3609// _In_reads_( cbData ) PCBYTE pbData,3610// SIZE_T cbData );3611//3612// Appends data to the KMAC state.3613//3614// This function must only be called after SymCryptKmacXxxInit or SymCryptKmacXxxAppend.3615// Calling SymCryptKmacXxxAppend after SymCryptKmacXxxExtract with bWipe=FALSE3616// is not well-defined. KMAC state must be initialized with SymCryptKmacXxxInit before3617// the first call to SymCryptKmacXxxAppend.3618//3619// VOID3620// SYMCRYPT_CALL3621// SymCryptKmacXxxExtract(3622// _Inout_ PSYMCRYPT_KMACXXX_STATE pState,3623// _Out_writes_( cbOutput ) PBYTE pbOutput,3624// SIZE_T cbOutput,3625// BOOLEAN bWipe);3626//3627// Generates KMAC output in XOF mode.3628//3629// Extract can only be called after an Init, Append or Extract call.3630// The state is cleared if bWipe=TRUE, otherwise further Extract calls3631// can be made to generate more output.3632//3633// VOID3634// SYMCRYPT_CALL3635// SymCryptKmacXxxResult(3636// _Inout_ PSYMCRYPT_KMACXXX_STATE pState,3637// _Out_writes_( SYMCRYPT_KMACXXX_RESULT_SIZE ) PBYTE pbResult);3638//3639// Produces SYMCRYPT_KMACXXX_RESULT_SIZE bytes of output from the KMAC state.3640// The state is wiped on return.3641//3642// This function internally calls SymCryptKmacXxxResultEx with result size3643// SYMCRYPT_KMACXXX_RESULT_SIZE.3644// If Result is called in XOF mode (i.e., after an Extract with bWipe=FALSE), it3645// performs a final extraction of SYMCRYPT_KMACXXX_RESULT_SIZE bytes in XOF mode3646// and clears the state afterwards.3647// Result function does not re-initialize the state for a new computation like3648// the Result for hash functions do. Computing a new MAC with the same key3649// requires calling the SymCryptKmacXxxInit function first.3650//3651// VOID3652// SYMCRYPT_CALL3653// SymCryptKmacXxxResultEx(3654// _Inout_ PSYMCRYPT_KMACXXX_STATE pState,3655// _Out_writes_( cbResult ) PBYTE pbResult,3656// SIZE_T cbResult);3657//3658// Produces cbResult bytes of output from the KMAC state. The state is3659// wiped on return.3660//3661// If ResultEx is called in XOF mode (i.e., after an Extract with bWipe=FALSE), it3662// performs a final extraction of cbResult bytes in XOF mode and clears the state3663// afterwards.3664// ResultEx function does not re-initialize the state for a new computation like3665// the Result for hash functions do. Computing a new MAC with the same key3666// requires calling the SymCryptKmacXxxInit function first.3667//366836693670//3671// KMAC1283672//3673#define SYMCRYPT_KMAC128_RESULT_SIZE SYMCRYPT_CSHAKE128_RESULT_SIZE3674#define SYMCRYPT_KMAC128_INPUT_BLOCK_SIZE SYMCRYPT_CSHAKE128_INPUT_BLOCK_SIZE36753676VOID3677SYMCRYPT_CALL3678SymCryptKmac128(3679_In_ PCSYMCRYPT_KMAC128_EXPANDED_KEY pExpandedKey,3680_In_reads_bytes_( cbInput ) PCBYTE pbInput,3681SIZE_T cbInput,3682_Out_writes_bytes_( SYMCRYPT_KMAC128_RESULT_SIZE ) PBYTE pbResult);36833684VOID3685SYMCRYPT_CALL3686SymCryptKmac128Ex(3687_In_ PCSYMCRYPT_KMAC128_EXPANDED_KEY pExpandedKey,3688_In_reads_bytes_( cbInput ) PCBYTE pbInput,3689SIZE_T cbInput,3690_Out_writes_bytes_( cbResult ) PBYTE pbResult,3691SIZE_T cbResult);369236933694SYMCRYPT_ERROR3695SYMCRYPT_CALL3696SymCryptKmac128ExpandKey(3697_Out_ PSYMCRYPT_KMAC128_EXPANDED_KEY pExpandedKey,3698_In_reads_bytes_( cbKey ) PCBYTE pbKey,3699SIZE_T cbKey);37003701SYMCRYPT_ERROR3702SYMCRYPT_CALL3703SymCryptKmac128ExpandKeyEx(3704_Out_ PSYMCRYPT_KMAC128_EXPANDED_KEY pExpandedKey,3705_In_reads_bytes_( cbKey ) PCBYTE pbKey,3706SIZE_T cbKey,3707_In_reads_bytes_( cbCustomizationString ) PCBYTE pbCustomizationString,3708SIZE_T cbCustomizationString);37093710VOID3711SYMCRYPT_CALL3712SymCryptKmac128Init(3713_Out_ PSYMCRYPT_KMAC128_STATE pState,3714_In_ PCSYMCRYPT_KMAC128_EXPANDED_KEY pExpandedKey);37153716VOID3717SYMCRYPT_CALL3718SymCryptKmac128Append(3719_Inout_ PSYMCRYPT_KMAC128_STATE pState,3720_In_reads_( cbData ) PCBYTE pbData,3721SIZE_T cbData );37223723VOID3724SYMCRYPT_CALL3725SymCryptKmac128Extract(3726_Inout_ PSYMCRYPT_KMAC128_STATE pState,3727_Out_writes_( cbOutput ) PBYTE pbOutput,3728SIZE_T cbOutput,3729BOOLEAN bWipe);37303731VOID3732SYMCRYPT_CALL3733SymCryptKmac128Result(3734_Inout_ PSYMCRYPT_KMAC128_STATE pState,3735_Out_writes_( SYMCRYPT_KMAC128_RESULT_SIZE ) PBYTE pbResult);37363737VOID3738SYMCRYPT_CALL3739SymCryptKmac128ResultEx(3740_Inout_ PSYMCRYPT_KMAC128_STATE pState,3741_Out_writes_( cbResult ) PBYTE pbResult,3742SIZE_T cbResult);37433744VOID3745SYMCRYPT_CALL3746SymCryptKmac128KeyCopy(_In_ PCSYMCRYPT_KMAC128_EXPANDED_KEY pSrc, _Out_ PSYMCRYPT_KMAC128_EXPANDED_KEY pDst);37473748VOID3749SYMCRYPT_CALL3750SymCryptKmac128StateCopy(_In_ const SYMCRYPT_KMAC128_STATE* pSrc, _Out_ SYMCRYPT_KMAC128_STATE* pDst);37513752VOID3753SYMCRYPT_CALL3754SymCryptKmac128Selftest(void);37553756extern const PCSYMCRYPT_MAC SymCryptKmac128Algorithm;37573758//3759// KMAC2563760//3761#define SYMCRYPT_KMAC256_RESULT_SIZE SYMCRYPT_CSHAKE256_RESULT_SIZE3762#define SYMCRYPT_KMAC256_INPUT_BLOCK_SIZE SYMCRYPT_CSHAKE256_INPUT_BLOCK_SIZE37633764VOID3765SYMCRYPT_CALL3766SymCryptKmac256(3767_In_ PCSYMCRYPT_KMAC256_EXPANDED_KEY pExpandedKey,3768_In_reads_bytes_( cbInput ) PCBYTE pbInput,3769SIZE_T cbInput,3770_Out_writes_bytes_( SYMCRYPT_KMAC256_RESULT_SIZE ) PBYTE pbResult);37713772VOID3773SYMCRYPT_CALL3774SymCryptKmac256Ex(3775_In_ PCSYMCRYPT_KMAC256_EXPANDED_KEY pExpandedKey,3776_In_reads_bytes_( cbInput ) PCBYTE pbInput,3777SIZE_T cbInput,3778_Out_writes_bytes_( cbResult ) PBYTE pbResult,3779SIZE_T cbResult);37803781SYMCRYPT_ERROR3782SYMCRYPT_CALL3783SymCryptKmac256ExpandKey(3784_Out_ PSYMCRYPT_KMAC256_EXPANDED_KEY pExpandedKey,3785_In_reads_bytes_( cbKey ) PCBYTE pbKey,3786SIZE_T cbKey);37873788SYMCRYPT_ERROR3789SYMCRYPT_CALL3790SymCryptKmac256ExpandKeyEx(3791_Out_ PSYMCRYPT_KMAC256_EXPANDED_KEY pExpandedKey,3792_In_reads_bytes_( cbKey ) PCBYTE pbKey,3793SIZE_T cbKey,3794_In_reads_bytes_( cbCustomizationString ) PCBYTE pbCustomizationString,3795SIZE_T cbCustomizationString);37963797VOID3798SYMCRYPT_CALL3799SymCryptKmac256Init(3800_Out_ PSYMCRYPT_KMAC256_STATE pState,3801_In_ PCSYMCRYPT_KMAC256_EXPANDED_KEY pExpandedKey);38023803VOID3804SYMCRYPT_CALL3805SymCryptKmac256Append(3806_Inout_ PSYMCRYPT_KMAC256_STATE pState,3807_In_reads_( cbData ) PCBYTE pbData,3808SIZE_T cbData );38093810VOID3811SYMCRYPT_CALL3812SymCryptKmac256Extract(3813_Inout_ PSYMCRYPT_KMAC256_STATE pState,3814_Out_writes_( cbOutput ) PBYTE pbOutput,3815SIZE_T cbOutput,3816BOOLEAN bWipe);38173818VOID3819SYMCRYPT_CALL3820SymCryptKmac256Result(3821_Inout_ PSYMCRYPT_KMAC256_STATE pState,3822_Out_writes_( SYMCRYPT_KMAC256_RESULT_SIZE ) PBYTE pbResult);38233824VOID3825SYMCRYPT_CALL3826SymCryptKmac256ResultEx(3827_Inout_ PSYMCRYPT_KMAC256_STATE pState,3828_Out_writes_( cbResult ) PBYTE pbResult,3829SIZE_T cbResult);38303831VOID3832SYMCRYPT_CALL3833SymCryptKmac256KeyCopy(_In_ PCSYMCRYPT_KMAC256_EXPANDED_KEY pSrc, _Out_ PSYMCRYPT_KMAC256_EXPANDED_KEY pDst);38343835VOID3836SYMCRYPT_CALL3837SymCryptKmac256StateCopy(_In_ const SYMCRYPT_KMAC256_STATE* pSrc, _Out_ SYMCRYPT_KMAC256_STATE* pDst);38383839VOID3840SYMCRYPT_CALL3841SymCryptKmac256Selftest(void);38423843extern const PCSYMCRYPT_MAC SymCryptKmac256Algorithm;384438453846////////////////////////////////////////////////////////////////////////////3847// POLY13053848//3849// Poly1305 is different from other MAC functions because a key can only3850// be used safely for a single message.3851// We do not follow the default API pattern for MAC functions as that invites3852// callers to compute multiple MACs per key.3853//38543855#define SYMCRYPT_POLY1305_RESULT_SIZE (16)3856#define SYMCRYPT_POLY1305_BLOCK_SIZE (16)3857#define SYMCRYPT_POLY1305_KEY_SIZE (32)38583859VOID3860SYMCRYPT_CALL3861SymCryptPoly1305(3862_In_reads_( SYMCRYPT_POLY1305_KEY_SIZE ) PCBYTE pbKey,3863_In_reads_( cbData ) PCBYTE pbData,3864SIZE_T cbData,3865_Out_writes_( SYMCRYPT_POLY1305_RESULT_SIZE ) PBYTE pbResult );3866// Compute a Poly1305 authentication with the provided key on the data buffer.3867// Note: A Poly1305 key may only be used for a single message.38683869VOID3870SYMCRYPT_CALL3871SymCryptPoly1305Init(3872_Out_ PSYMCRYPT_POLY1305_STATE pState,3873_In_reads_( SYMCRYPT_POLY1305_KEY_SIZE ) PCBYTE pbKey );3874// Starts an incremental Poly1305 computation.3875// Note: A Poly1305 key may only be used for a single message.38763877VOID3878SYMCRYPT_CALL3879SymCryptPoly1305Append(3880_Inout_ PSYMCRYPT_POLY1305_STATE pState,3881_In_reads_( cbData ) PCBYTE pbData,3882SIZE_T cbData );38833884VOID3885SYMCRYPT_CALL3886SymCryptPoly1305Result(3887_Inout_ PSYMCRYPT_POLY1305_STATE pState,3888_Out_writes_( SYMCRYPT_POLY1305_RESULT_SIZE ) PBYTE pbResult );3889// The state is wiped and not suitable for re-use.38903891VOID3892SYMCRYPT_CALL3893SymCryptPoly1305Selftest(void);38943895//3896// We do NOT define a SYMCRYPT_MAC structure SymCryptPoly1305Algorithm3897// for Poly1305 as it is a 1-time MAC function and cannot safely be used3898// by any KDF we have3899//3900// NOT DEFINED: extern const PCSYMCRYPT_MAC SymCryptPoly1305Algorithm;3901//39023903////////////////////////////////////////////////////////////////////////////3904// CHACHA20_POLY13053905//3906// This algorithm combines the CHACHA20 symmetric key stream cipher with3907// the POLY1305 MAC function as per RFC 8439.3908// The POLY1305 authenticator key is generated from the first 32 bytes3909// of the CHACHA20 keystream and is only valid for a single message.3910// For this reason each key and nonce combination passed to3911// SymCryptChaCha20Poly1305Encrypt MUST only be used once.3912//3913// The Src and Dst buffers can be identical or non-overlapping; partial overlaps3914// are not supported.3915//39163917SYMCRYPT_ERROR3918SYMCRYPT_CALL3919SymCryptChaCha20Poly1305Encrypt(3920_In_reads_( cbKey ) PCBYTE pbKey,3921SIZE_T cbKey, // Required. Key size MUST be 32 bytes.3922_In_reads_( cbNonce ) PCBYTE pbNonce,3923SIZE_T cbNonce, // Required. Nonce size MUST be 12 bytes.3924_In_reads_opt_( cbAuthData ) PCBYTE pbAuthData,3925SIZE_T cbAuthData, // Optional. Can be any size.3926_In_reads_( cbData ) PCBYTE pbSrc,3927_Out_writes_( cbData ) PBYTE pbDst,3928SIZE_T cbData, // Required. Max size is 274,877,906,880 bytes.3929_Out_writes_( cbTag ) PBYTE pbTag,3930SIZE_T cbTag ); // Required. Tag size MUST be 16 bytes.39313932SYMCRYPT_ERROR3933SYMCRYPT_CALL3934SymCryptChaCha20Poly1305Decrypt(3935_In_reads_( cbKey ) PCBYTE pbKey,3936SIZE_T cbKey, // Required. Key size MUST be 32 bytes.3937_In_reads_( cbNonce ) PCBYTE pbNonce,3938SIZE_T cbNonce, // Required. Nonce size MUST be 12 bytes.3939_In_reads_opt_( cbAuthData ) PCBYTE pbAuthData,3940SIZE_T cbAuthData, // Optional. Can be any size.3941_In_reads_( cbData ) PCBYTE pbSrc,3942_Out_writes_( cbData ) PBYTE pbDst,3943SIZE_T cbData, // Required. Max size is 274,877,906,880 bytes.3944_In_reads_( cbTag ) PCBYTE pbTag,3945SIZE_T cbTag ); // Required. Tag size MUST be 16 bytes.39463947VOID3948SYMCRYPT_CALL3949SymCryptChaCha20Poly1305Selftest(void);39503951////////////////////////////////////////////////////////////////////////////3952// MARVIN323953//3954// Marvin is a checksum function optimized for speed on small inputs.3955// IT IS NOT A CRYPTOGRAPHIC HASH FUNCTION.3956// Marvin lacks the security properties of a cryptographic hash function.3957// DO NOT USE FOR ANY SECURITY USE.3958//3959// A randomizable checksum function has essentially the same API as a MAC3960// function. We use the SymCrypt MAC API here, with the difference3961// that we use the word 'seed' rather than 'key'.3962//3963// See the description above of the generic MAC API for details on how3964// these functions are used. Wherever the MAC API talks about keys, this3965// applies to the seed for Marvin32.3966//3967// The randomization is useful for hash tables.3968// There are DOS attacks where an attacker generates many inputs that3969// hash to the same location in the hash table. Some hash table implementations3970// then use O(n^2) CPU time, allowing a DOS attack.3971// The randomization provided by the seed avoids this attack if:3972// - The seed is unpredictable and unknown to the attacker.3973// - The attacker cannot learn information about the output of the checksum function.3974// In particular, if an attacker can measure how long it takes to add each3975// element in a hash table, they might be able to determine enough information about3976// the output of the checksum function to recover the seed. Of course,3977// once that is done the DOS attack is once again possible.3978//3979// SymCrypt provides a default seed for applications that don't need a seed.3980//3981// FUTURE IMPROVEMENTS:3982// At the moment it is relatively expensive to change the seed.3983// If needed, we can add a facility to modify the seed faster than3984// re-running the ExpandSeed function.3985//39863987#define SYMCRYPT_MARVIN32_RESULT_SIZE (8)3988#define SYMCRYPT_MARVIN32_SEED_SIZE (8)3989#define SYMCRYPT_MARVIN32_INPUT_BLOCK_SIZE (4)39903991SYMCRYPT_ERROR3992SYMCRYPT_CALL3993SymCryptMarvin32ExpandSeed(3994_Out_ PSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed,3995_In_reads_(cbSeed) PCBYTE pbSeed,3996SIZE_T cbSeed );3997//3998// The seed must be 8 bytes (= SYMCRYPT_MARVIN32_SEED_SIZE).3999// Use of the all-zero seed is not recommended as it has some undesirable properties.4000// Note that a pre-expanded default seed is provided for applications that do not wish to control4001// their seed. Such applications do not need to call SymCryptMarvin32ExpandSeed4002//40034004extern PCSYMCRYPT_MARVIN32_EXPANDED_SEED const SymCryptMarvin32DefaultSeed;40054006PCSYMCRYPT_MARVIN32_EXPANDED_SEED4007SYMCRYPT_CALL4008SymCryptGetMarvin32DefaultSeed( void );4009//4010// Returns a pointer to the default Marvin32 seed.4011//40124013VOID4014SYMCRYPT_CALL4015SymCryptMarvin32SeedCopy( _In_ PCSYMCRYPT_MARVIN32_EXPANDED_SEED pSrc,4016_Out_ PSYMCRYPT_MARVIN32_EXPANDED_SEED pDst );40174018VOID4019SYMCRYPT_CALL4020SymCryptMarvin32(4021_In_ PCSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed,4022_In_reads_( cbData ) PCBYTE pbData,4023SIZE_T cbData,4024_Out_writes_( SYMCRYPT_MARVIN32_RESULT_SIZE ) PBYTE pbResult );4025//4026// If the application does not wish to use a seed, a default expanded seed is provided.4027// Callers can pass SymCryptMarvin32DefaultSeed as the first argument.4028//40294030VOID4031SYMCRYPT_CALL4032SymCryptMarvin32StateCopy(4033_In_ PCSYMCRYPT_MARVIN32_STATE pSrc,4034_In_opt_ PCSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed,4035_Out_ PSYMCRYPT_MARVIN32_STATE pDst );403640374038VOID4039SYMCRYPT_CALL4040SymCryptMarvin32Init( _Out_ PSYMCRYPT_MARVIN32_STATE pState,4041_In_ PCSYMCRYPT_MARVIN32_EXPANDED_SEED pExpandedSeed);40424043VOID4044SYMCRYPT_CALL4045SymCryptMarvin32Append( _Inout_ PSYMCRYPT_MARVIN32_STATE pState,4046_In_reads_( cbData ) PCBYTE pbData,4047SIZE_T cbData );40484049VOID4050SYMCRYPT_CALL4051SymCryptMarvin32Result(4052_Inout_ PSYMCRYPT_MARVIN32_STATE pState,4053_Out_writes_( SYMCRYPT_MARVIN32_RESULT_SIZE ) PBYTE pbResult );405440554056VOID4057SYMCRYPT_CALL4058SymCryptMarvin32Selftest(void);405940604061//==========================================================================4062// BLOCK CIPHERS4063//==========================================================================4064//4065// For a block cipher XXX the following minimal functions, types, and constants are defined:4066//4067// SYMCRYPT_XXX_BLOCK_SIZE4068//4069// A constant giving is the block size, in bytes, of the algorithm.4070//4071//4072// SYMCRYPT_XXX_EXPANDED_KEY4073// Type which contains a key with all the pre-computations performed.4074// This is an opaque type whose structure can change at will.4075// It should only be used for transient computations in a single executable4076// and not be stored or transferred to a different environment.4077// The pointer and const-pointer versions are also declared4078// (PSYMCRYPOT_XXX_EXPANDED_KEY and PCSYMCRYPT_XXX_EXPANDED_KEY).4079//4080// The EXPANDED_KEY structure contains keying material and should be wiped4081// once it is no longer used. (See SymCryptWipe & SymCryptWipeKnownSize)4082//4083// Once initialized, multiple threads can use the same expanded key object simultaneously4084// for different block cipher computations as the expanded key is not modified once initialized.4085//4086// SymCryptXxxBlockCipher4087// A SYMCRYPT_BLOCKCIPHER structure that provides a description4088// of the block cipher and its primary functions. This is used by cipher modes to pass4089// all the block-cipher specific information in a single structure.4090//4091//4092// SYMCRYPT_ERROR4093// SYMCRYPT_CALL4094// SymCryptXxxExpandKey( _Out_ PSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,4095// _In_reads_(cbKey) PCBYTE pbKey,4096// SIZE_T cbKey );4097//4098// Prepare a key for future use by the Xxx algorithm.4099// This function performs pre-computations on the key4100// to speed up the actual block cipher computations later, and stores the result as an expanded key.4101// The expanded key must be kept unchanged until all computations that use the key are finished.4102// When the key is no longer needed the expanded key structure should be wiped.4103//4104// Different algorithms pose different requirements on the length of the key.4105// If the key that is provided is of an unsupported length the SYMCRYPT_WRONG_KEY_SIZE error is returned.4106// In this case the expanded key structure will not contain any keying material and does not have to be wiped.4107//4108//4109// VOID4110// SYMCRYPT_CALL4111// SymCryptXxxEncrypt( _In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,4112// _In_reads_( SYMCRYPT_XXX_BLOCK_SIZE ) PCBYTE pbSrc,4113// _Out_writes_( SYMCRYPT_XXX_BLOCK_SIZE ) PBYTE pbDst );4114//4115// Encrypt a single block.4116//4117//4118// VOID4119// SYMCRYPT_CALL4120// SymCryptXxxDecrypt( _In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,4121// _In_reads_( SYMCRYPT_XXX_BLOCK_SIZE ) PCBYTE pbSrc,4122// _Out_writes_( SYMCRYPT_XXX_BLOCK_SIZE ) PBYTE pbDst );4123//4124// Decrypt a single block.4125//4126//4127// --------------------------------------------------------------------------------------------------------------4128// In addition to these elementary encrypt block/decrypt block functions a block cipher may also implement4129// optimized versions of CBC encryption, CBC decryption, CBC-MAC, and CTR encryption. Not all block ciphers4130// do implement these.4131// All block cipher modes are always available through the generic block cipher mode functions.4132//4133// VOID4134// SYMCRYPT_CALL4135// SymCryptXxxCbcEncrypt(4136// _In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,4137// _Inout_updates_( SYMCRYPT_XXX_BLOCK_SIZE ) PBYTE pbChainingValue,4138// _In_reads_( cbData ) PCBYTE pbSrc,4139// _Out_writes_( cbData ) PBYTE pbDst,4140// SIZE_T cbData );4141//4142// Encrypt data using the CBC chaining mode.4143// On entry the pbChainingValue is the IV which is xorred into the first plaintext block of the CBC encryption.4144// On exit the pbChainingValue is updated to the last ciphertext block of the result.4145// This allows a longer CBC encryption to be done incrementally.4146//4147// cbData must be a multiple of the block size. For efficiency reasons this routine does not return an error4148// if cbData is not a proper multiple; instead the result is undefined. The routine might hang,4149// round cbData down to a multiple of the block size, or return random data that cannot be decrypted.4150//4151// The pbSrc and pbDst buffers may be the same, or they may be non-overlapping. However, they may4152// not be partially overlapping.4153//4154//4155// VOID4156// SYMCRYPT_CALL4157// SymCryptXxxCbcDecrypt(4158// _In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,4159// _Inout_updates_( SYMCRYPT_XXX_BLOCK_SIZE ) PBYTE pbChainingValue,4160// _In_reads_( cbData ) PCBYTE pbSrc,4161// _Out_writes_( cbData ) PBYTE pbDst,4162// SIZE_T cbData );4163//4164// Decrypt data using the CBC chaining mode.4165// On entry the pbChainingValue is the IV to be xorred into the first plaintext block of the CBC decryption.4166// On exit the pbChainingValue is updated to the last ciphertext block of the input.4167// This allows a longer CBC decryption to be done incrementally.4168//4169// cbData must be a multiple of the block size. For efficiency reasons this routine does not return an error4170// if cbData is not a proper multiple; instead the result is undefined. The routine might hang,4171// round cbData down to a multiple of the block size, or return random data.4172//4173// The pbSrc and pbDst buffers may be the same, or they may be non-overlapping. However, they may4174// not be partially overlapping.4175//4176//4177// VOID4178// SYMCRYPT_CALL4179// SymCryptXxxCbcMac(4180// _In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,4181// _Inout_updates_( SYMCRYPT_XXX_BLOCK_SIZE ) PBYTE pbChainingValue,4182// _In_reads_( cbData ) PCBYTE pbData,4183// SIZE_T cbData );4184//4185// Compute a CBC-MAC on the input data.4186// On entry the pbChainingValue is the current chaining state of the CBC-MAC computation; this routine4187// updates the state to reflect the chaining state after MACing the data.4188// cbData must be a multiple of the block size.4189// This function is NOT intended for general use; rather it is a high-performance primitive to support4190// implementations of other cipher modes like CCM and CMAC.4191// Note: If a key is used for CBC-MAC computations it should NOT be used for any encryptions.4192//4193//4194// VOID4195// SYMCRYPT_CALL4196// SymCryptXxxCtrMsb64(4197// _In_ PCSYMCRYPT_XXX_EXPANDED_KEY pExpandedKey,4198// _Inout_updates_( SYMCRYPT_XXX_BLOCK_SIZE ) PBYTE pbChainingValue,4199// _In_reads_( cbData ) PCBYTE pbSrc,4200// _Out_writes_( cbData ) PBYTE pbDst,4201// SIZE_T cbData );4202//4203// Perform a CTR encryption on the data. (Note: CTR encryption and decryption are the same operation.)4204// On entry pbChainingValue contains the first counter value to be used. On exit it contains4205// the next counter value to be used.4206// The increment function treats the last 8 bytes of the pbChainingValue string as an integer4207// in most-significant-byte-first format, and increments this integer.4208// Thus, the last byte is incremented the fastest.4209// The pbSrc and pbDst buffers may be identical or non-overlapping, but they may not partially overlap.4210// cbData must be a multiple of the block size.4211//4212//4213// VOID4214// SYMCRYPT_CALL4215// SymCryptXxxSelftest(void);4216//4217// Perform a minimal self-test on the XXX algorithm.4218// This function is designed to be used for achieving FIPS 140-2 compliance or4219// to provide a simple self-test when an application starts.4220//4221// If an error is detected the fatal callback routine is called.4222//4223// We do not provide self-tests for the various cipher modes. There are too many4224// (block cipher, key size, cipher mode) combinations and CNG performs the self tests4225// on the outside APIs, not on the internal APIs.4226// We retain a self test on the basic algorithm to help internal library testing.4227422842294230////////////////////////////////////////////////////////////////////////////4231// AES4232//4233// The AES block cipher per FIPS 1974234//4235// WARNING:4236// Unless this code is running on a CPU with AES-NI instructions,4237// the AES implementation makes extensive use of table lookups to implement the S-boxes of the algorithm.4238// This violates our current crypto implementation guidelines and opens up a possible side-channel attack4239// through information leakage via the memory caching system of the CPU.4240//4241// Unfortunately there is no known software fix for this that does not lead to an order of magnitude performance loss.4242// An implementation that is 10x slower will not be used by anybody and is useless, so we implement a fast4243// version that uses table lookups. (Just like all other systems we know of.)4244//4245// The risk of this type of side-channel attack is limited as it requires malicious code to run on the same4246// machine as the code being attacked.4247//4248// At the time of writing (Apr 2007) there are no approved alternative encryption algorithms that do not4249// use table lookups. NIST and NSA are aware of this problem, but so far we have not seen any indication4250// that they consider this important enough to create an alternative encryption algorithm that does not4251// rely on table lookups as much.4252//42534254#define SYMCRYPT_AES_BLOCK_SIZE (16)42554256SYMCRYPT_ERROR4257SYMCRYPT_CALL4258SymCryptAesExpandKey(4259_Out_ PSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,4260_In_reads_(cbKey) PCBYTE pbKey,4261SIZE_T cbKey );42624263//4264// The SymCryptAesExpandKeyEncryptOnly creates an AES-expanded key that can ONLY be used4265// for AES encryption operations. There are no safeguards when you use it for decryption; you get the wrong4266// result if you try.4267//4268SYMCRYPT_ERROR4269SYMCRYPT_CALL4270SymCryptAesExpandKeyEncryptOnly(4271_Out_ PSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,4272_In_reads_(cbKey) PCBYTE pbKey,4273SIZE_T cbKey );42744275VOID4276SYMCRYPT_CALL4277SymCryptAesKeyCopy( _In_ PCSYMCRYPT_AES_EXPANDED_KEY pSrc,4278_Out_ PSYMCRYPT_AES_EXPANDED_KEY pDst );42794280VOID4281SYMCRYPT_CALL4282SymCryptAesEncrypt(4283_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,4284_In_reads_( SYMCRYPT_AES_BLOCK_SIZE ) PCBYTE pbSrc,4285_Out_writes_( SYMCRYPT_AES_BLOCK_SIZE ) PBYTE pbDst );42864287VOID4288SYMCRYPT_CALL4289SymCryptAesDecrypt(4290_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,4291_In_reads_( SYMCRYPT_AES_BLOCK_SIZE ) PCBYTE pbSrc,4292_Out_writes_( SYMCRYPT_AES_BLOCK_SIZE ) PBYTE pbDst );42934294VOID4295SYMCRYPT_CALL4296SymCryptAesEcbEncrypt(4297_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,4298_In_reads_( cbData ) PCBYTE pbSrc,4299_Out_writes_( cbData ) PBYTE pbDst,4300SIZE_T cbData );43014302VOID4303SYMCRYPT_CALL4304SymCryptAesEcbDecrypt(4305_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,4306_In_reads_( cbData ) PCBYTE pbSrc,4307_Out_writes_( cbData ) PBYTE pbDst,4308SIZE_T cbData );43094310VOID4311SYMCRYPT_CALL4312SymCryptAesCbcEncrypt(4313_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,4314_Inout_updates_( SYMCRYPT_AES_BLOCK_SIZE ) PBYTE pbChainingValue,4315_In_reads_( cbData ) PCBYTE pbSrc,4316_Out_writes_( cbData ) PBYTE pbDst,4317SIZE_T cbData );43184319VOID4320SYMCRYPT_CALL4321SymCryptAesCbcDecrypt(4322_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,4323_Inout_updates_( SYMCRYPT_AES_BLOCK_SIZE ) PBYTE pbChainingValue,4324_In_reads_( cbData ) PCBYTE pbSrc,4325_Out_writes_( cbData ) PBYTE pbDst,4326SIZE_T cbData );43274328VOID4329SYMCRYPT_CALL4330SymCryptAesCbcMac(4331_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,4332_Inout_updates_( SYMCRYPT_AES_BLOCK_SIZE ) PBYTE pbChainingValue,4333_In_reads_( cbData ) PCBYTE pbData,4334SIZE_T cbData );43354336VOID4337SYMCRYPT_CALL4338SymCryptAesCtrMsb64(4339_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,4340_Inout_updates_( SYMCRYPT_AES_BLOCK_SIZE ) PBYTE pbChainingValue,4341_In_reads_( cbData ) PCBYTE pbSrc,4342_Out_writes_( cbData ) PBYTE pbDst,4343SIZE_T cbData );43444345//4346// There are many optimized implementations for various AES modes.4347// To test them all would pull in all the code for these modes.4348// We solve this by letting the caller specify a bitmask of modes to be tested.4349// Under the following circumstances this will avoid pulling in unnecessary code:4350// - The argument is a compile-time constant.4351// - The compiler implements the usual constant propagation optimizations.4352//4353// Note: GCM, CCM, and XTS are NOT tested by this function.43544355#define SYMCRYPT_AES_SELFTEST_BASE 0x01 // tests AesEncrypt & AesDecrypt4356#define SYMCRYPT_AES_SELFTEST_ECB 0x02 // ECB mode4357#define SYMCRYPT_AES_SELFTEST_CBC 0x04 // CBC mode4358#define SYMCRYPT_AES_SELFTEST_CBCMAC 0x08 // CBC-mac4359#define SYMCRYPT_AES_SELFTEST_CTR 0x10 // all CTR modes43604361#define SYMCRYPT_AES_SELFTEST_ALL 0x1f43624363VOID4364SYMCRYPT_CALL4365SymCryptAesSelftest( UINT32 maskTestsToRun );43664367extern const PCSYMCRYPT_BLOCKCIPHER SymCryptAesBlockCipher;436843694370////////////////////////////////////////////////////////////////////////////4371// DES4372//4373// The DES block cipher per FIPS-46-34374//4375// WARNING:4376// DES is no longer considered secure and should not be used.4377// Per the Crypto SDL, any use of DES in Microsoft code requires a Crypto board exemption4378//4379// The DES implementation makes extensive use of table lookups to implement the S-boxes of the algorithm.4380// This violates our current crypto implementation guidelines and opens up a possible side-channel attack4381// through information leakage via the memory caching system of the CPU.4382//43834384#define SYMCRYPT_DES_BLOCK_SIZE (8)43854386SYMCRYPT_ERROR4387SYMCRYPT_CALL4388SymCryptDesExpandKey(4389_Out_ PSYMCRYPT_DES_EXPANDED_KEY pExpandedKey,4390_In_reads_(cbKey) PCBYTE pbKey,4391SIZE_T cbKey );4392//4393// The key must be 8 bytes long. The parity bits in the key are ignored and can be any value.4394//43954396VOID4397SYMCRYPT_CALL4398SymCryptDesEncrypt(4399_In_ PCSYMCRYPT_DES_EXPANDED_KEY pExpandedKey,4400_In_reads_( SYMCRYPT_DES_BLOCK_SIZE ) PCBYTE pbSrc,4401_Out_writes_( SYMCRYPT_DES_BLOCK_SIZE ) PBYTE pbDst );44024403VOID4404SYMCRYPT_CALL4405SymCryptDesDecrypt(4406_In_ PCSYMCRYPT_DES_EXPANDED_KEY pExpandedKey,4407_In_reads_( SYMCRYPT_DES_BLOCK_SIZE ) PCBYTE pbSrc,4408_Out_writes_( SYMCRYPT_DES_BLOCK_SIZE ) PBYTE pbDst );440944104411VOID4412SYMCRYPT_CALL4413SymCryptDesSetOddParity(4414_Inout_updates_( cbData ) PBYTE pbData,4415_In_ SIZE_T cbData );4416//4417// Set each byte to have odd parity by possibly flipping bit 0.4418// This is the parity used by DES, and is needed for compatibility.4419// The parity bit is ignored by the DES key expansion.4420//44214422VOID4423SYMCRYPT_CALL4424SymCryptDesSelftest(void);44254426extern const PCSYMCRYPT_BLOCKCIPHER SymCryptDesBlockCipher;44274428////////////////////////////////////////////////////////////////////////////4429// 3DES4430//4431// The triple-DES block cipher4432//4433// WARNING:4434// The DES implementation makes extensive use of table lookups to implement the S-boxes of the algorithm.4435// This violates our current crypto implementation guidelines and opens up a possible side-channel attack4436// through information leakage via the memory caching system of the CPU.4437//44384439#define SYMCRYPT_3DES_BLOCK_SIZE (8)44404441SYMCRYPT_ERROR4442SYMCRYPT_CALL4443SymCrypt3DesExpandKey(4444_Out_ PSYMCRYPT_3DES_EXPANDED_KEY pExpandedKey,4445_In_reads_(cbKey) PCBYTE pbKey,4446SIZE_T cbKey );4447//4448// If the provided key is 24 bytes long this expands a 3-key 3DES key. If 16 bytes are provided it4449// expands a 2-key 3DES. If 8 bytes are provided it creates the 3-key equivalent of the single4450// key des encryption. The parity bits in the key are ignored.4451//44524453VOID4454SYMCRYPT_CALL4455SymCrypt3DesEncrypt(4456_In_ PCSYMCRYPT_3DES_EXPANDED_KEY pExpandedKey,4457_In_reads_( SYMCRYPT_3DES_BLOCK_SIZE ) PCBYTE pbSrc,4458_Out_writes_( SYMCRYPT_3DES_BLOCK_SIZE )PBYTE pbDst );44594460VOID4461SYMCRYPT_CALL4462SymCrypt3DesDecrypt(4463_In_ PCSYMCRYPT_3DES_EXPANDED_KEY pExpandedKey,4464_In_reads_( SYMCRYPT_3DES_BLOCK_SIZE ) PCBYTE pbSrc,4465_Out_writes_( SYMCRYPT_3DES_BLOCK_SIZE )PBYTE pbDst );44664467VOID4468SYMCRYPT_CALL4469SymCrypt3DesCbcEncrypt(4470_In_ PCSYMCRYPT_3DES_EXPANDED_KEY pExpandedKey,4471_Inout_updates_( SYMCRYPT_3DES_BLOCK_SIZE ) PBYTE pbChainingValue,4472_In_reads_( cbData ) PCBYTE pbSrc,4473_Out_writes_( cbData ) PBYTE pbDst,4474SIZE_T cbData );44754476VOID4477SYMCRYPT_CALL4478SymCrypt3DesCbcDecrypt(4479_In_ PCSYMCRYPT_3DES_EXPANDED_KEY pExpandedKey,4480_Inout_updates_( SYMCRYPT_3DES_BLOCK_SIZE ) PBYTE pbChainingValue,4481_In_reads_( cbData ) PCBYTE pbSrc,4482_Out_writes_( cbData ) PBYTE pbDst,4483SIZE_T cbData );44844485VOID4486SYMCRYPT_CALL4487SymCrypt3DesSelftest(void);44884489extern const PCSYMCRYPT_BLOCKCIPHER SymCrypt3DesBlockCipher;44904491////////////////////////////////////////////////////////////////////////////4492// DESX4493//4494// The DESX block cipher.4495//4496// Use of DESX is not recommended.4497//44984499#define SYMCRYPT_DESX_BLOCK_SIZE (8)45004501SYMCRYPT_ERROR4502SYMCRYPT_CALL4503SymCryptDesxExpandKey(4504_Out_ PSYMCRYPT_DESX_EXPANDED_KEY pExpandedKey,4505_In_reads_(cbKey) PCBYTE pbKey,4506SIZE_T cbKey );45074508VOID4509SYMCRYPT_CALL4510SymCryptDesxEncrypt(4511_In_ PCSYMCRYPT_DESX_EXPANDED_KEY pExpandedKey,4512_In_reads_( SYMCRYPT_DESX_BLOCK_SIZE ) PCBYTE pbSrc,4513_Out_writes_( SYMCRYPT_DESX_BLOCK_SIZE )PBYTE pbDst );45144515VOID4516SYMCRYPT_CALL4517SymCryptDesxDecrypt(4518_In_ PCSYMCRYPT_DESX_EXPANDED_KEY pExpandedKey,4519_In_reads_( SYMCRYPT_DESX_BLOCK_SIZE ) PCBYTE pbSrc,4520_Out_writes_( SYMCRYPT_DESX_BLOCK_SIZE )PBYTE pbDst );452145224523VOID4524SYMCRYPT_CALL4525SymCryptDesxSelftest(void);45264527extern const PCSYMCRYPT_BLOCKCIPHER SymCryptDesxBlockCipher;45284529////////////////////////////////////////////////////////////////////////////4530// RC24531//4532// The RC2 block cipher4533//4534// WARNING:4535// Use of RC2 is not recommended for many reasons.4536//4537// The RC2 implementation makes extensive use of table lookups to implement the S-boxes of the algorithm.4538// This violates our current crypto implementation guidelines and opens up a possible side-channel attack4539// through information leakage via the memory caching system of the CPU.4540//45414542#define SYMCRYPT_RC2_BLOCK_SIZE (8)45434544SYMCRYPT_ERROR4545SYMCRYPT_CALL4546SymCryptRc2ExpandKey(4547_Out_ PSYMCRYPT_RC2_EXPANDED_KEY pExpandedKey,4548_In_reads_(cbKey) PCBYTE pbKey,4549SIZE_T cbKey );4550//4551// The default effective key size is 8*cbKey. Note that this is NOT the default used in4552// the old RSA32 library which used a default effective key size of 40 bits.4553// That is too dangerous a default to implement. We chose 8*cbKey rather than 1024 as4554// our choice provides slightly better mixing of the key bytes into the expanded key.4555//45564557SYMCRYPT_ERROR4558SYMCRYPT_CALL4559SymCryptRc2ExpandKeyEx(4560_Out_ PSYMCRYPT_RC2_EXPANDED_KEY pExpandedKey,4561_In_reads_(cbKey) PCBYTE pbKey,4562SIZE_T cbKey,4563UINT32 effectiveKeySizeInBits );4564//4565// Rc2 has an option to limit the effective key size, which means the key expansion function has an extra4566// parameter.4567//4568// The effective key size in bits may be any value from 9..1024. If it is larger than 8*cbKey it does4569// not significantly affect the key strength. However, the expanded key will always depend on the4570// effective key size; expanding the same string of key bytes with differ effective key sizes leads4571// to different expanded keys and different encryption functions.4572//4573// The original default was an effective key size of 40 bits.4574//4575// Do not allow your attacker to choose the effective key size. RC2 seems vulnerable to4576// related-effective-key-size attacks.4577//45784579VOID4580SYMCRYPT_CALL4581SymCryptRc2Encrypt(4582_In_ PCSYMCRYPT_RC2_EXPANDED_KEY pExpandedKey,4583_In_reads_( SYMCRYPT_RC2_BLOCK_SIZE ) PCBYTE pbSrc,4584_Out_writes_( SYMCRYPT_RC2_BLOCK_SIZE ) PBYTE pbDst );45854586VOID4587SYMCRYPT_CALL4588SymCryptRc2Decrypt(4589_In_ PCSYMCRYPT_RC2_EXPANDED_KEY pExpandedKey,4590_In_reads_( SYMCRYPT_RC2_BLOCK_SIZE ) PCBYTE pbSrc,4591_Out_writes_( SYMCRYPT_RC2_BLOCK_SIZE ) PBYTE pbDst );459245934594VOID4595SYMCRYPT_CALL4596SymCryptRc2Selftest(void);45974598extern const PCSYMCRYPT_BLOCKCIPHER SymCryptRc2BlockCipher;459946004601//==========================================================================4602// BLOCK CIPHER MODES4603//==========================================================================4604//4605// Block cipher modes use the block cipher description tables to implement4606// the various modes in a block-cipher independent way.4607//4608// Some block ciphers implement optimized versions of the block cipher modes.4609// These functions call that optimized version, but calling the block-cipher specific4610// function has less overhead.4611//4612// Note that these functions will only work with SymCrypt-provided block ciphers.4613// They are not designed to be used with externally provided block ciphers.4614// (The SYMCRYPT_BLOCKCIPHER structure is a private one not available to callers.)4615//46164617typedef enum _SYMCRYPT_BLOCKCIPHER_ID4618{4619SYMCRYPT_BLOCKCIPHER_ID_NULL = 0,4620SYMCRYPT_BLOCKCIPHER_ID_AES = 1,4621SYMCRYPT_BLOCKCIPHER_ID_DES = 2,4622SYMCRYPT_BLOCKCIPHER_ID_3DES = 3,4623SYMCRYPT_BLOCKCIPHER_ID_DESX = 4,4624SYMCRYPT_BLOCKCIPHER_ID_RC2 = 54625} SYMCRYPT_BLOCKCIPHER_ID;46264627PCSYMCRYPT_BLOCKCIPHER4628SYMCRYPT_CALL4629SymCryptGetBlockCipher( SYMCRYPT_BLOCKCIPHER_ID blockCipherId );4630//4631// Returns a pointer to the block cipher structure for the specified block cipher ID.4632// Returns NULL if the block cipher ID is invalid.4633//46344635VOID4636SYMCRYPT_CALL4637SymCryptEcbEncrypt(4638_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4639_In_ PCVOID pExpandedKey,4640_In_reads_( cbData ) PCBYTE pbSrc,4641_Out_writes_( cbData ) PBYTE pbDst,4642SIZE_T cbData );4643//4644// Generic ECB encryption routine for block ciphers.4645//4646// - pBlockCipher is a pointer to the block cipher description table.4647// Suitable description tables for all ciphers in this library have been pre-defined.4648// - pExpandedKey points to the expanded key to use. This generic function uses PVOID so there4649// is no type safety to ensure that the expanded key and the encryption function match.4650// - pbSrc is the plaintext input buffer. The plaintext and ciphertext buffers may be4651// identical (in-place encryption) or non-overlapping, but they may not partially overlap.4652// - cbData. Number of bytes to encrypt. This must be a multiple of the block size.4653// - pbDst is the result buffer. It may be identical to pbPlaintext or non-overlapping,4654// but it may not partially overlap with the pbPlaintext buffer.4655//46564657VOID4658SYMCRYPT_CALL4659SymCryptEcbDecrypt(4660_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4661_In_ PCVOID pExpandedKey,4662_In_reads_( cbData ) PCBYTE pbSrc,4663_Out_writes_( cbData ) PBYTE pbDst,4664SIZE_T cbData );4665//4666// Generic ECB decryption routine for block ciphers.4667//4668// - pBlockCipher is a pointer to the block cipher description table.4669// Suitable description tables for all ciphers in this library have been pre-defined.4670// - pExpandedKey points to the expanded key to use. This generic function uses PVOID so there4671// is no type safety to ensure that the expanded key and the encryption function match.4672// - pbSrc is the plaintext input buffer. The plaintext and ciphertext buffers may be4673// identical (in-place encryption) or non-overlapping, but they may not partially overlap.4674// - cbData. Number of bytes to encrypt. This must be a multiple of the block size.4675// - pbDst is the result buffer. It may be identical to pbPlaintext or non-overlapping,4676// but it may not partially overlap with the pbPlaintext buffer.4677//467846794680VOID4681SYMCRYPT_CALL4682SymCryptCbcEncrypt(4683_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4684_In_ PCVOID pExpandedKey,4685_Inout_updates_( pBlockCipher->blockSize )4686PBYTE pbChainingValue,4687_In_reads_( cbData ) PCBYTE pbSrc,4688_Out_writes_( cbData ) PBYTE pbDst,4689SIZE_T cbData );46904691//4692// Generic CBC encryption routine for block ciphers.4693//4694// - pBlockCipher is a pointer to the block cipher description table.4695// Suitable description tables for all ciphers in this library have been pre-defined.4696// - pExpandedKey points to the expanded key to use. This generic function uses PVOID so there4697// is no type safety to ensure that the expanded key and the encryption function match.4698// - pbChainingValue points to the chaining value. On entry it is the IV value for the CBC4699// encryption, on return it is the last ciphertext block. A long message can be encrypted4700// piecewise in multiple calls; at the end of one call the pbChainingValue buffer will contain4701// the correct chaining value for encrypting the next piece of the message.4702// Once the encryption is finished the value in the chaining buffer is no longer needed.4703// - pbSrc is the plaintext input buffer. The plaintext and ciphertext buffers may be4704// identical (in-place encryption) or non-overlapping, but they may not partially overlap.4705// - cbData. Number of bytes to encrypt. This must be a multiple of the block size.4706// - pbDst is the result buffer. It may be identical to pbPlaintext or non-overlapping,4707// but it may not partially overlap with the pbPlaintext buffer.4708//470947104711VOID4712SYMCRYPT_CALL4713SymCryptCbcDecrypt(4714_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4715_In_ PCVOID pExpandedKey,4716_Inout_updates_( pBlockCipher->blockSize )4717PBYTE pbChainingValue,4718_In_reads_( cbData ) PCBYTE pbSrc,4719_Out_writes_( cbData ) PBYTE pbDst,4720SIZE_T cbData );47214722//4723// This is the decryption version of SymCryptCbcEncrypt.4724// All parameters have the same explanation and restrictions.:4725//472647274728VOID4729SYMCRYPT_CALL4730SymCryptCbcMac(4731_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4732_In_ PCVOID pExpandedKey,4733_Inout_updates_( pBlockCipher->blockSize )4734PBYTE pbChainingValue,4735_In_reads_( cbData ) PCBYTE pbSrc,4736SIZE_T cbData );4737//4738// This function implements the same function as SymCryptCbcEncrypt except that4739// it does not produce a ciphertext output.4740// All other restrictions apply.4741// The pbChainingValue is the only output provided.4742//4743// This is the primitive operation used by other modes of operation,4744// and some platforms have special optimizations for this primitive.4745// As we expose special APIs for some algorithms, we provide the generic function so that it4746// can be used for all algorithms.4747//474847494750VOID4751SYMCRYPT_CALL4752SymCryptCtrMsb64(4753_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4754_In_ PCVOID pExpandedKey,4755_Inout_updates_( pBlockCipher->blockSize )4756PBYTE pbChainingValue,4757_In_reads_( cbData ) PCBYTE pbSrc,4758_Out_writes_( cbData ) PBYTE pbDst,4759SIZE_T cbData );4760//4761// This function implements the CTR cipher mode.4762// It is not intended to be used as-is, rather it is a building block for modes like CCM.4763// On some platforms we have optimized code for AES-CTR, on other platforms4764// we use this generic construction to achieve the same effect.4765//4766// Note that in CTR mode encryption and decryption are the same operation.4767//4768// - pBlockCipher is a pointer to the block cipher description table.4769// Suitable description tables for all ciphers in this library have been pre-defined.4770// - pExpandedKey points to the expanded key to use. This generic function uses PVOID so there4771// is no type safety to ensure that the expanded key and the encryption function match.4772// - pbChainingValue points to the chaining value. On entry it is the first counter value to be4773// used. On exit is the next counter value to be used.4774// The pbChainingValue is incremented by cbData/blockSize.4775// The increment function treats the last 8 bytes of pbChaining a MSBfirst integer4776// and increments the integer representation by one for each block.4777// - pbSrc is the input data buffer that will be encrypted/decrypted.4778// - cbData. Number of bytes to encrypt/decrypt. This must be a multiple of the block size.4779// - pbDst is the output buffer that receives the encrypted/decrypted data. The input and output4780// buffers may be the same or non-overlapping, but may not partially overlap.4781//47824783VOID4784SYMCRYPT_CALL4785SymCryptCfbEncrypt(4786_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4787SIZE_T cbShift,4788_In_ PCVOID pExpandedKey,4789_Inout_updates_( pBlockCipher->blockSize )4790PBYTE pbChainingValue,4791_In_reads_( cbData ) PCBYTE pbSrc,4792_Out_writes_( cbData ) PBYTE pbDst,4793SIZE_T cbData );4794//4795// Encrypt a buffer using the CFB cipher mode.4796//4797// This implements the CFB mode, with selected shift amount (in bytes).4798// In general, one block cipher encryption is used for each cbShift bytes4799// of plaintext, which can be slow.4800// Use of this cipher mode is not recommended.4801//4802// - pBlockCipher is a pointer to the block cipher description table.4803// Suitable description tables for all ciphers in this library have been pre-defined.4804// - cbShift is the shift value (in bytes) of the CFB mode.4805// The only supported values are 1 and the block size.4806// - pExpandedKey points to the expanded key to use. This generic function uses PVOID so there4807// is no type safety to ensure that the expanded key and the encryption function match.4808// - pbChainingValue points to the chaining value. On entry and exit it4809// contains the last blockSize ciphertext bytes.4810// - pbSrc is the input data buffer that will be encrypted/decrypted.4811// - cbData. Number of bytes to encrypt/decrypt.4812// Must be a multiple of cbShift, or a multiple of the block size if cbShift = 0.4813// - pbDst is the output buffer that receives the encrypted/decrypted data. The input and output4814// buffers may be the same or non-overlapping, but may not partially overlap.4815//48164817VOID4818SYMCRYPT_CALL4819SymCryptCfbDecrypt(4820_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4821SIZE_T cbShift,4822_In_ PCVOID pExpandedKey,4823_Inout_updates_( pBlockCipher->blockSize )4824PBYTE pbChainingValue,4825_In_reads_( cbData ) PCBYTE pbSrc,4826_Out_writes_( cbData ) PBYTE pbDst,4827SIZE_T cbData );4828//4829// The corresponding decryption routine.4830//48314832VOID4833SYMCRYPT_CALL4834SymCryptPaddingPkcs7Add(4835SIZE_T cbBlockSize,4836_In_reads_(cbSrc) PCBYTE pbSrc,4837SIZE_T cbSrc,4838_Out_writes_to_(cbDst, *pcbResult) PBYTE pbDst,4839SIZE_T cbDst,4840SIZE_T* pcbResult);4841//4842// Prerequisites:4843// cbBlockSize is a power of 2 and < 2564844// cbDst >= cbSrc - cbSrc % cbBlockSize + cbBlockSize4845//4846// Add PKCS7 block padding to a message4847// The input data (pbSrc,cbSrc) is padded with between 1 and cbBlockSize bytes so that4848// the length of the result is a multiple of cbBlockSize.4849// The padded message is written to the pbDst buffer.4850// The length of the padded message is returned in *pcbResult.4851//4852// If pbSrc == pbDst this function avoids copying all the data.4853// Note that cbSrc == cbDst is not valid as it violates the prerequisites.4854// Padding a message with cbSrc == 0 is valid.4855//4856// Note:4857// Any whole blocks in Src are merely copied to Dst.4858// Callers can either process the whole message in this call,4859// or handle the whole blocks themselves and only pass the last few bytes of the message to this function.4860//4861// Note: the prerequisites are not checked by this function; if they are not satisfied4862// the behaviour of the function is undefined.4863//486448654866SYMCRYPT_ERROR4867SYMCRYPT_CALL4868SymCryptPaddingPkcs7Remove(4869SIZE_T cbBlockSize,4870_In_reads_(cbSrc) PCBYTE pbSrc,4871SIZE_T cbSrc,4872_Out_writes_to_(cbDst, *pcbResult) PBYTE pbDst,4873SIZE_T cbDst,4874SIZE_T* pcbResult);4875//4876// Prerequisites:4877// - cbBlockSize is a power of 2 and < 2564878// - cbSrc is a multiple of cbBlockSize4879// - cbSrc is greater than zero (at least equals to cbBlockSize)4880//4881// Remove PKCS7 block padding from a message in a side-channel safe way.4882// *** see below for important rules the caller should follow w.r.t. side-channel safety ***4883// The input data (pbSrc, cbSrc) is a valid PKCS7 padded message for the given blocksize.4884// This function removes the padding, copies the result to the (pbDst, cbDst) buffer,4885// and returns the size of the result in *pcbResult.4886//4887// This function only supports padding with a size up to the block size.4888//4889// If pbSrc == pbDst this function avoids copying data.4890//4891// The following errors are returned:4892// - SYMCRYPT_INVALID_ARGUMENT if cbSrc or the padding is invalid4893// - SYMCRYPT_BUFFER_TOO_SMALL if cbDst < size of the unpadded message4894// If cbDst >= cbSrc the SYMCRYPT_BUFFER_TOO_SMALL error will not be returned.4895// Even if an error is returned, the pbDst buffer may or may not contain data from the message.4896// Callers should wipe the buffer even if an error is returned.4897//4898// Note: Removal of PKCS7 padding is extremely sensitive to side channels.4899// For example, if a message is encrypted with AES-CBC and the attacker can modify4900// the ciphertext and then determine whether a padding error occurs during decryption,4901// then the attacker can use the presence or absence of the error to decrypt the message itself.4902// This function takes great care not to reveal whether an error occurred, and hides4903// the size of the unpadded message. This is even true when writing to pbDst. If cbDst is large4904// enough, the code will write cbSrc-1 bytes to pbDst, using masking to only update the bytes of the4905// message and leaving the other bytes in pbDst unchanged.4906// Callers should take great care not to reveal the returned error or success,4907// or the size of the returned message, until they have authenticated4908// the source of the data.4909//4910// In particular, any mapping of the error code should be done in a side-channel safe way.4911// See the SymCryptMapUint32() function for a side-channel safe way to map error codes.4912//4913// The error caused by an invalid cbSrc value is not hidden from side channels as this does not reveal any4914// secret information.4915//4916// Note: callers can either process the whole message in this call,4917// or process the whole blocks themselves and only pass the last block to this function.49184919////////////////////////////4920// CCM4921////////////////////////////49224923SYMCRYPT_ERROR4924SYMCRYPT_CALL4925SymCryptCcmValidateParameters(4926_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4927_In_ SIZE_T cbNonce,4928_In_ SIZE_T cbAssociatedData,4929_In_ UINT64 cbData,4930_In_ SIZE_T cbTag4931);4932//4933// To achieve maximum performance, CCM functions do not check for valid parameters.4934// Passing invalid parameters can lead to buffer overflows.4935// Callers who want to validate their CCM parameters can call this function.4936// Note: In Checked builds some CCM functions might fatal out when invalid parameters are4937// passed.4938//493949404941VOID4942SYMCRYPT_CALL4943SymCryptCcmEncrypt(4944_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4945_In_ PCVOID pExpandedKey,4946_In_reads_( cbNonce ) PCBYTE pbNonce,4947SIZE_T cbNonce,4948_In_reads_opt_( cbAuthData ) PCBYTE pbAuthData,4949SIZE_T cbAuthData,4950_In_reads_( cbData ) PCBYTE pbSrc,4951_Out_writes_( cbData ) PBYTE pbDst,4952SIZE_T cbData,4953_Out_writes_( cbTag ) PBYTE pbTag,4954SIZE_T cbTag );49554956//4957// Encrypt a buffer using the block cipher in CCM mode.4958// - pBlockCipher points to the block cipher description table.4959// - pExpandedKey points to the expanded key for the block cipher.4960// - pbNonce: Pointer to the nonce for this encryption. For a single key, each nonce4961// value may be used at most once to encrypt data. Re-using nonce values leads4962// to catastrophic loss of security.4963// - cbNonce: number of bytes in the nonce: 7 <= cbNonce <= 13.4964// - pbAuthData: pointer to the associated authentication data. This data is not encrypted4965// but it is included in the authentication. Use NULL if not used.4966// - cbAuthData: # bytes of associated authentication data. (0 if not used)4967// - pbSrc: plaintext input4968// - pbDst: ciphertext output. The ciphertext buffer may be identical to the plaintext4969// buffer, or non-overlapping. The ciphertext is also cbData bytes long.4970// - cbData: # bytes of plaintext input. The maximum length is 2^{8(15-cbNonce)} - 1 bytes.4971// - pbTag: buffer that will receive the authentication tag.4972// - cbTag: size of tag. cbTag must be one of {4, 6, 8, 10, 12, 14, 16}.4973//497449754976SYMCRYPT_ERROR4977SYMCRYPT_CALL4978SymCryptCcmDecrypt(4979_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,4980_In_ PCVOID pExpandedKey,4981_In_reads_( cbNonce ) PCBYTE pbNonce,4982SIZE_T cbNonce,4983_In_reads_opt_( cbAuthData ) PCBYTE pbAuthData,4984SIZE_T cbAuthData,4985_In_reads_( cbData ) PCBYTE pbSrc,4986_Out_writes_( cbData ) PBYTE pbDst,4987SIZE_T cbData,4988_In_reads_( cbTag ) PCBYTE pbTag,4989SIZE_T cbTag );4990//4991// Decrypt a buffer using the block cipher in CCM mode.4992// See SymCryptCcmEncrypt for a description of the parameters. This function decrypts rather than4993// encrypts, and as a result the pbTag parameter is read rather than filled.4994//4995// If the tag value is not correct the SYMCRYPT_AUTHENTICATION_FAILURE error is returned and the pbDst buffer4996// is wiped of any plaintext.4997// Note: While checking the authentication the purported plaintext is stored in pbDst. It is not safe to reveal4998// purported plaintext when the authentication has not been checked. (Doing so would reveal key stream information4999// that can be used to decrypt any message encrypted with the same nonce value.) Thus, users should be careful5000// to not reveal the pbDst buffer until this function returns (e.g. through other threads or sharing memory).5001//50025003//5004// We also provide functions for incremental computation of CCM encryption and decryption. See the functions5005// above for a description of the parameters and restrictions.5006// In particular, note that the restriction on revealing the plaintext for unauthenticated decryptions holds5007// for all the decrypted data, even when the decryption is done incrementally.5008//5009// SYMCRYPT_CCM_STATE5010// Ongoing state of an incremental CCM encryption or decryption operation.5011//50125013VOID5014SYMCRYPT_CALL5015SymCryptCcmInit(5016_Out_ PSYMCRYPT_CCM_STATE pState,5017_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,5018_In_ PCVOID pExpandedKey,5019_In_reads_( cbNonce ) PCBYTE pbNonce,5020SIZE_T cbNonce,5021_In_reads_opt_( cbAuthData ) PCBYTE pbAuthData,5022SIZE_T cbAuthData,5023UINT64 cbData,5024SIZE_T cbTag );5025//5026// Initialize a CCM computation. Note that the ultimate data length has to be provided.5027// The pBlockCipher and pExpandedKey structures must remain unchanged until the CCM computation is finished.5028//50295030VOID5031SYMCRYPT_CALL5032SymCryptCcmEncryptPart(5033_Inout_ PSYMCRYPT_CCM_STATE pState,5034_In_reads_( cbData ) PCBYTE pbSrc,5035_Out_writes_( cbData ) PBYTE pbDst,5036SIZE_T cbData );50375038VOID5039SYMCRYPT_CALL5040SymCryptCcmEncryptFinal(5041_Inout_ PSYMCRYPT_CCM_STATE pState,5042_Out_writes_( cbTag ) PBYTE pbTag,5043SIZE_T cbTag );5044//5045// Note: passing cbTag is redundant but necessary for SAL purposes.5046//50475048VOID5049SYMCRYPT_CALL5050SymCryptCcmDecryptPart(5051_Inout_ PSYMCRYPT_CCM_STATE pState,5052_In_reads_( cbData ) PCBYTE pbSrc,5053_Out_writes_( cbData ) PBYTE pbDst,5054SIZE_T cbData );50555056SYMCRYPT_ERROR5057SYMCRYPT_CALL5058SymCryptCcmDecryptFinal(5059_Inout_ PSYMCRYPT_CCM_STATE pState,5060_In_reads_( cbTag ) PCBYTE pbTag,5061SIZE_T cbTag );5062//5063// WARNING: When the authentication fails the data already decrypted may not be revealed.5064// This function cannot wipe the plaintext buffers; the caller is responsible for ensuring5065// the plaintext is not revealed.5066//50675068VOID5069SYMCRYPT_CALL5070SymCryptCcmSelftest(void);5071//5072// Self test for CCM cipher mode5073//50745075///////////////////////////////////////5076// GCM5077///////////////////////////////////////5078//5079// The GCM algorithm per SP 800-38D.5080// GMAC is just GCM with an empty data string; all the data is put in the pbAuthData buffer.5081//50825083SYMCRYPT_ERROR5084SYMCRYPT_CALL5085SymCryptGcmValidateParameters(5086_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,5087_In_ SIZE_T cbNonce,5088_In_ UINT64 cbAssociatedData,5089_In_ UINT64 cbData,5090_In_ SIZE_T cbTag5091);5092//5093// To achieve maximum performance, GCM functions do not check for valid parameters.5094// Passing invalid parameters can lead to buffer overflows.5095// Callers who want to validate their GCM parameters can call this function.5096// Note: In Checked builds some GCM functions might fatal out when invalid parameters are5097// passed.5098//509951005101SYMCRYPT_ERROR5102SYMCRYPT_CALL5103SymCryptGcmExpandKey(5104_Out_ PSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey,5105_In_ PCSYMCRYPT_BLOCKCIPHER pBlockCipher,5106_In_reads_( cbKey ) PCBYTE pbKey,5107SIZE_T cbKey );5108//5109// Create an expanded key suitable for GCM5110//51115112VOID5113SYMCRYPT_CALL5114SymCryptGcmKeyCopy( _In_ PCSYMCRYPT_GCM_EXPANDED_KEY pSrc, _Out_ PSYMCRYPT_GCM_EXPANDED_KEY pDst );51155116//5117// Create a copy of an expanded key5118//51195120VOID5121SYMCRYPT_CALL5122SymCryptGcmEncrypt(5123_In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey,5124_In_reads_( cbNonce ) PCBYTE pbNonce,5125SIZE_T cbNonce,5126_In_reads_opt_( cbAuthData ) PCBYTE pbAuthData,5127SIZE_T cbAuthData,5128_In_reads_( cbData ) PCBYTE pbSrc,5129_Out_writes_( cbData ) PBYTE pbDst,5130SIZE_T cbData,5131_Out_writes_( cbTag ) PBYTE pbTag,5132SIZE_T cbTag );51335134//5135// Encrypt a buffer using the block cipher in GCM mode.5136// - pExpandedKey points to the expanded key for GCM.5137// - pbNonce: Pointer to the nonce for this encryption. For a single key, each nonce5138// value may be used at most once to encrypt data. Re-using nonce values leads5139// to catastrophic loss of security. Only 12-byte nonces are supported,5140// per the SP800-38D section 5.2.1.1 recommendation.5141// - cbNonce: number of bytes in the nonce, must be 12.5142// - pbAuthData: pointer to the associated authentication data. This data is not encrypted5143// but it is included in the authentication. Use NULL if not used.5144// - cbAuthData: # bytes of associated authentication data. (0 if not used)5145// - pbSrc: plaintext input5146// - pbDst: ciphertext output. The ciphertext buffer may be identical to the plaintext5147// buffer, or non-overlapping. The ciphertext is also cbData bytes long.5148// - cbData: # bytes of plaintext input. The maximum length is 2^{36} - 32 bytes.5149// - pbTag: buffer that will receive the authentication tag.5150// - cbTag: size of tag. cbTag must be one of {12, 13, 14, 15, 16} per SP800-38D5151// section 5.2.1.2. The optional shorter tag sizes (4 and 8) are not supported.5152//515351545155SYMCRYPT_ERROR5156SYMCRYPT_CALL5157SymCryptGcmDecrypt(5158_In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey,5159_In_reads_( cbNonce ) PCBYTE pbNonce,5160SIZE_T cbNonce,5161_In_reads_opt_( cbAuthData ) PCBYTE pbAuthData,5162SIZE_T cbAuthData,5163_In_reads_( cbData ) PCBYTE pbSrc,5164_Out_writes_( cbData ) PBYTE pbDst,5165SIZE_T cbData,5166_In_reads_( cbTag ) PCBYTE pbTag,5167SIZE_T cbTag );5168//5169// Decrypt a buffer using the block cipher in GCM mode.5170// See SymCryptGcmEncrypt for a description of the parameters. This function decrypts rather than5171// encrypts, and as a result the pbTag parameter is read rather than filled.5172// If the tag value is not correct the SYMCRYPT_AUTHENTICATION_FAILURE error is returned and the pbDst buffer5173// is wiped of any plaintext.5174// Note: While checking the authentication the purported plaintext is stored in pbDst. It is not safe to reveal5175// purported plaintext when the authentication has not been checked. (Doing so would reveal key stream information5176// that can be used to decrypt any message encrypted with the same nonce value.) Thus, users should be careful5177// to not reveal the pbDst buffer until this function returns (e.g. through other threads or sharing memory).5178//51795180//5181// We also provide functions for incremental computation of GCM encryption and decryption. See the functions5182// above for a description of the parameters and restrictions.5183// In particular, note that the restriction on revealing the plaintext for unauthenticated decryptions holds5184// for all the decrypted data, even when the decryption is done incrementally.5185//5186//5187// SYMCRYPT_GCM_STATE5188// Ongoing state of an incremental GCM encryption or decryption operation.5189//51905191VOID5192SYMCRYPT_CALL5193SymCryptGcmInit(5194_Out_ PSYMCRYPT_GCM_STATE pState,5195_In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey,5196_In_reads_( cbNonce ) PCBYTE pbNonce,5197SIZE_T cbNonce );5198//5199// Initialize a GCM computation.5200// The pBlockCipher and pExpandedKey structures must remain unchanged until the GCM computation is finished.5201//52025203VOID5204SYMCRYPT_CALL5205SymCryptGcmStateCopy(5206_In_ PCSYMCRYPT_GCM_STATE pSrc,5207_In_opt_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKeyCopy,5208_Out_ PSYMCRYPT_GCM_STATE pDst );5209//5210// Copy a GCM state.5211// If pExpandedKeyCopy is NULL, then the new pDst state uses the same expanded key as pSrc.5212// If pExpandedKeyCopy is not NULL, it must point to a copy of the expanded key of the pSrc state.5213// This new expanded key will be used as the expanded key for pDst.5214//52155216VOID5217SYMCRYPT_CALL5218SymCryptGcmAuthPart(5219_Inout_ PSYMCRYPT_GCM_STATE pState,5220_In_reads_opt_( cbData ) PCBYTE pbAuthData,5221SIZE_T cbData );5222//5223// Incrementally process the authentication data. This function can be called multiple times5224// after the SymCryptGcmInit function. It may not be called after any encrypt or decrypt5225// function has been called on the GCM state.5226//52275228VOID5229SYMCRYPT_CALL5230SymCryptGcmEncryptPart(5231_Inout_ PSYMCRYPT_GCM_STATE pState,5232_In_reads_( cbData ) PCBYTE pbSrc,5233_Out_writes_( cbData ) PBYTE pbDst,5234SIZE_T cbData );52355236VOID5237SYMCRYPT_CALL5238SymCryptGcmEncryptFinal(5239_Inout_ PSYMCRYPT_GCM_STATE pState,5240_Out_writes_( cbTag ) PBYTE pbTag,5241SIZE_T cbTag );52425243VOID5244SYMCRYPT_CALL5245SymCryptGcmDecryptPart(5246_Inout_ PSYMCRYPT_GCM_STATE pState,5247_In_reads_( cbData ) PCBYTE pbSrc,5248_Out_writes_( cbData ) PBYTE pbDst,5249SIZE_T cbData );52505251SYMCRYPT_ERROR5252SYMCRYPT_CALL5253SymCryptGcmDecryptFinal(5254_Inout_ PSYMCRYPT_GCM_STATE pState,5255_In_reads_( cbTag ) PCBYTE pbTag,5256SIZE_T cbTag );5257//5258// Returns SYMCRYPT_AUTHENTICATION_FAILURE if the tag value does not match.5259//526052615262VOID5263SYMCRYPT_CALL5264SymCryptGcmSelftest(void);5265//5266// Self test for GCM cipher mode5267//526852695270//==========================================================================5271// SESSION BASED APIs5272//==========================================================================527352745275SYMCRYPT_ERROR5276SYMCRYPT_CALL5277SymCryptSessionSenderInit(5278_Inout_ PSYMCRYPT_SESSION pSession,5279UINT32 senderId,5280UINT32 flags );5281//5282// Initialize an encryption session object. The default nonce size of 12B is used - 8B are provided5283// by message number, 4B by senderId.5284// - pSession: Pointer to an uninitialized session object.5285// - senderId: The id of the sender (must be unique for each user of a given key).5286// Callers should either choose a senderId which is specific to the sender, or5287// at least to the software and role in a system in which a key is being used.5288// Two encryption sessions using the same key and senderId leads to catastrophic loss of security.5289// - No flags are specified for this function5290//5291// Remarks:5292// On some platforms use of a session object requires use of a mutex. On those platforms this5293// function will call SymCryptCallbackAllocateMutexFastInproc and may indicate failure by returning5294// SYMCRYPT_MEMORY_ALLOCATION_FAILURE if a mutex object cannot be created.5295// Callers must call SymCryptSessionDestroy to ensure any associated allocated mutex object is freed5296// either before calling another Init function on the SYMCRYPT_SESSION object, and instead of directly5297// calling SymCryptWipeKnownSize on the object.5298//52995300SYMCRYPT_ERROR5301SYMCRYPT_CALL5302SymCryptSessionReceiverInit(5303_Inout_ PSYMCRYPT_SESSION pSession,5304UINT32 senderId,5305UINT32 flags );5306//5307// Initialize an decryption session object. The default nonce size of 12B is used - 8B are provided5308// by message number, 4B by senderId.5309// - pSession: Pointer to an uninitialized session object.5310// - senderId: The id of the sender (must be unique for each user of a given key).5311// Callers should either choose a senderId which is specific to the sender, or5312// at least to the software and role in a system in which a key is being used.5313// The id used in a decryption session must be the same as the id used in the corresponding5314// encryption session (i.e. sender and receiver must agree upon a senderId for their5315// communication session)5316// - No flags are specified for this function5317//5318// Remarks:5319// On some platforms use of a session object requires use of a mutex. On those platforms this5320// function will call SymCryptCallbackAllocateMutexFastInproc and may indicate failure by returning5321// SYMCRYPT_MEMORY_ALLOCATION_FAILURE if a mutex object cannot be created.5322// Callers must call SymCryptSessionDestroy to ensure any associated allocated mutex object is freed5323// either before calling another Init function on the SYMCRYPT_SESSION object, and instead of directly5324// calling SymCryptWipeKnownSize on the object.5325//53265327VOID5328SYMCRYPT_CALL5329SymCryptSessionDestroy(5330_Inout_ PSYMCRYPT_SESSION pSession );5331//5332// Clear session object and free any data associated with the object (i.e. allocated locks)5333// After this call the memory used for pSession is uninitialized and can be used for other purposes.5334// Note that it is not safe to just wipe the memory of the session object as the session5335// object contains pointers to other allocations.5336// The only way to safely destroy a session is to use this function.5337//53385339SYMCRYPT_ERROR5340SYMCRYPT_CALL5341SymCryptSessionGcmEncrypt(5342_Inout_ PSYMCRYPT_SESSION pSession,5343_In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey,5344_In_reads_opt_( cbAuthData ) PCBYTE pbAuthData,5345SIZE_T cbAuthData,5346_In_reads_( cbData ) PCBYTE pbSrc,5347_Out_writes_( cbData ) PBYTE pbDst,5348SIZE_T cbData,5349_Out_writes_( cbTag ) PBYTE pbTag,5350SIZE_T cbTag,5351_Out_opt_ PUINT64 pu64MessageNumber );5352//5353// Encrypt a buffer, in a series, using the block cipher in GCM mode.5354// - pSession points to the session object for this series of GCM encryptions. It handles5355// ensuring Nonce uniqueness across several encryption calls using the same key. The message5356// number in the pSession object is atomically incremented by this call.5357// If too many messages (2^64 - 2^32) have been encrypted with the same session object,5358// SYMCRYPT_INVALID_ARGUMENT is returned and no encryption takes place. This should never5359// occur in real use!5360// - pExpandedKey points to the expanded key for GCM.5361// - pbAuthData: pointer to the associated authentication data. This data is not encrypted5362// but it is included in the authentication. Use NULL if not used.5363// - cbAuthData: # bytes of associated authentication data. (0 if not used)5364// - pbSrc: plaintext input5365// - pbDst: ciphertext output. The ciphertext buffer may be identical to the plaintext5366// buffer, or non-overlapping. The ciphertext is also cbData bytes long.5367// - cbData: # bytes of plaintext input. The maximum length is 2^{36} - 32 bytes.5368// - pbTag: buffer that will receive the authentication tag.5369// - cbTag: size of tag. cbTag must be one of {12, 13, 14, 15, 16} per SP800-38D5370// section 5.2.1.2. The optional shorter tag sizes (4 and 8) are not supported.5371// - pu64MessageNumber: Optional message number output for this encryption. A unique message5372// number is extracted from the pSession object, this output is set to the value used in5373// the encryption. The first message number generated in a session will have the value 1,5374// and subsequent message numbers will be taken by atomically incrementing the counter.5375//53765377SYMCRYPT_ERROR5378SYMCRYPT_CALL5379SymCryptSessionGcmDecrypt(5380_Inout_ PSYMCRYPT_SESSION pSession,5381UINT64 messageNumber,5382_In_ PCSYMCRYPT_GCM_EXPANDED_KEY pExpandedKey,5383_In_reads_opt_( cbAuthData ) PCBYTE pbAuthData,5384SIZE_T cbAuthData,5385_In_reads_( cbData ) PCBYTE pbSrc,5386_Out_writes_( cbData ) PBYTE pbDst,5387SIZE_T cbData,5388_In_reads_( cbTag ) PCBYTE pbTag,5389SIZE_T cbTag );5390//5391// Decrypt a buffer, in a series, using the block cipher in GCM mode.5392// - pSession points to the session object for this series of GCM decryptions. It handles5393// ensuring Nonce uniqueness across several decryption calls using the same key, particularly5394// ensuring there are no replays.5395// - messageNumber: The message number to be used for this decryption, forming part of the Nonce.5396// When performing decryption in a session, it is guaranteed that no 2 decryptions using the5397// same session and same message number can succeed. This is to provide protection against5398// replay attacks.5399// In order to provide this guarantee, pSession tracks a window of used message numbers5400// preceding the largest messageNumber successfully used so far in the decryption session.5401// A SYMCRYPT_SESSION_REPLAY_FAILURE error will be returned if either:5402// a) messageNumber is less than the smallest message number that can be tracked for replays5403// b) messageNumber is within the window that can be tracked for replays, and the message5404// number is marked as already having been used in a successful decryption in this session5405// In either case, the destination buffer is wiped.5406// See SymCryptSessionGcmEncrypt for a description of the other parameters. This function decrypts5407// rather than encrypts, and as a result the pbTag parameter is read rather than filled.5408// If the tag value is not correct the SYMCRYPT_AUTHENTICATION_FAILURE error is returned and the5409// pbDst buffer is wiped of any plaintext.5410// Note: While checking the authentication the purported plaintext is stored in pbDst. It is not safe to reveal5411// purported plaintext when the authentication has not been checked. (Doing so would reveal key stream information5412// that can be used to decrypt any message encrypted with the same nonce value.) Thus, users should be careful5413// to not reveal the pbDst buffer until this function returns (e.g. through other threads or sharing memory).5414//541554165417//==========================================================================5418// STREAM CIPHERS5419//==========================================================================54205421////////////////////////////////////////////////////////////////////////////5422// RC45423//5424// The RC4 stream cipher5425//5426// Use of RC4 is not recommended.5427//5428// The RC4 implementation makes extensive use of table lookups to implement the S-boxes of the algorithm.5429// This violates our current crypto implementation guidelines and opens up a possible side-channel attack5430// through information leakage via the memory caching system of the CPU.5431//54325433SYMCRYPT_ERROR5434SYMCRYPT_CALL5435SymCryptRc4Init(5436_Out_ PSYMCRYPT_RC4_STATE pState,5437_In_reads_( cbKey ) PCBYTE pbKey,5438_In_ SIZE_T cbKey );5439//5440// Initialize an RC4 encryption/decryption state.5441// WARNING: the most common error in using RC4 is to use the same key to encrypt two different pieces of data.5442// This is insecure and should never be done; you need a unique key for each data element that is encrypted.5443//54445445VOID5446SYMCRYPT_CALL5447SymCryptRc4Crypt(5448_Inout_ PSYMCRYPT_RC4_STATE pState,5449_In_reads_( cbData ) PCBYTE pbSrc,5450_Out_writes_( cbData ) PBYTE pbDst,5451_In_ SIZE_T cbData );5452//5453// Encrypt or Decrypt data using the RC4 state. Note that the RC4 state is updated and therefore this5454// function cannot be used by two threads simultaneously using the same state object.5455//54565457VOID5458SYMCRYPT_CALL5459SymCryptRc4Selftest(void);546054615462//5463// ChaCha205464//5465// The ChaCha20 stream cipher is specified in RFC 7539 and referenced by RFC 79055466// which specifies the ChaCha20-Poly1305 TLS cipher suite.5467//5468// ChaCha is a random-access stream cipher. It is possible to jump to any part of5469// the key stream and start en/decrypting there.5470// We support this by allowing the caller to select the position in the key stream5471// to use.5472//54735474SYMCRYPT_ERROR5475SYMCRYPT_CALL5476SymCryptChaCha20Init(5477_Out_ PSYMCRYPT_CHACHA20_STATE pState,5478_In_reads_( cbKey ) PCBYTE pbKey,5479_In_ SIZE_T cbKey,5480_In_reads_( cbNonce ) PCBYTE pbNonce,5481SIZE_T cbNonce,5482UINT64 offset );5483//5484// Initialize a ChaCha20 en/decryption state.5485// Key must be 32 bytes5486// Nonce must be 12 bytes5487// offset is the position into the key stream that the next encrypt/decrypt5488// operation will use. Requirement: 0 <= offset < 2^385489// The ChaCha documentation is formulated in terms of a 'counter' or 'initial counter'.5490// Callers can set offset = 64 * <counter> to achieve the same results.5491//5492// An error is returned only for invalid key or nonce sizes.5493//5494// A single (key,nonce) pair defines a key stream of 256 GB.5495// Any part of that key stream can be used to encrypt a message, or part of a5496// message.5497// Note that it is critical that each key stream byte is used only once; thus5498// callers have to ensure that for any key, each nonce is used at most once for5499// a message, and messages cannot use any part of the 256 GB key stream more than5500// once.5501//55025503VOID5504SYMCRYPT_CALL5505SymCryptChaCha20SetOffset(5506_Inout_ PSYMCRYPT_CHACHA20_STATE pState,5507UINT64 offset );5508//5509// Specify the offset into the key stream where the next encrypt/decrypt operation5510// will start.5511// Requirement: 0 <= offset < 2^385512//55135514VOID5515SYMCRYPT_CALL5516SymCryptChaCha20Crypt(5517_Inout_ PSYMCRYPT_CHACHA20_STATE pState,5518_In_reads_( cbData ) PCBYTE pbSrc,5519_Out_writes_( cbData ) PBYTE pbDst,5520SIZE_T cbData );5521//5522// Encrypt or Decrypt data using the CHACHA20 state.5523// The Src data is xorred with the key stream generated from the state, and the result stored5524// in the Dst buffer. The Src and Dst buffer can be identical or non-overlapping; partial overlaps5525// are not supported.5526// As the state is updated two threads cannot en/decrypt with the same state at the same time.5527// The key stream used is the one generated from the key and nonce, starting at the specified5528// offset into the key stream. This function updates the offset of the state by adding cbData to5529// it so that the next call will use the next part of the key stream.5530// Any attempt to use the key stream at offset >= 2^38 will result in catastrophic loss of security.5531//55325533VOID5534SYMCRYPT_CALL5535SymCryptChaCha20Selftest(void);55365537553855395540//==========================================================================5541// KEY DERIVATION ALGORITHMS5542//==========================================================================55435544////////////////////////////////////////////////////////////////////////////5545// PBKDF25546//5547// Generic KDF parameter handling:5548// - Generic parameter is passed in the Salt input;5549// - iterationCnt is set to 1.5550//55515552SYMCRYPT_ERROR5553SYMCRYPT_CALL5554SymCryptPbkdf2ExpandKey(5555_Out_ PSYMCRYPT_PBKDF2_EXPANDED_KEY pExpandedKey,5556_In_ PCSYMCRYPT_MAC macAlgorithm,5557_In_reads_(cbKey) PCBYTE pbKey,5558SIZE_T cbKey );55595560SYMCRYPT_ERROR5561SYMCRYPT_CALL5562SymCryptPbkdf2Derive(5563_In_ PCSYMCRYPT_PBKDF2_EXPANDED_KEY pExpandedKey,5564_In_reads_opt_(cbSalt) PCBYTE pbSalt,5565SIZE_T cbSalt,5566UINT64 iterationCnt,5567_Out_writes_(cbResult) PBYTE pbResult,5568SIZE_T cbResult);55695570SYMCRYPT_ERROR5571SYMCRYPT_CALL5572SymCryptPbkdf2(5573PCSYMCRYPT_MAC macAlgorithm,5574_In_reads_(cbKey) PCBYTE pbKey,5575SIZE_T cbKey,5576_In_reads_opt_(cbSalt) PCBYTE pbSalt,5577SIZE_T cbSalt,5578UINT64 iterationCnt,5579_Out_writes_(cbResult) PBYTE pbResult,5580SIZE_T cbResult);55815582//5583// Because the self-test pulls in the associated MAC function,5584// we have several self-tests; each of which tests the PBKDF2 implementation5585// using the specified MAC function.5586// This allows a FIPS module to run the self-test with the MAC function it already5587// uses internally.5588//5589// More can be added when needed.5590//55915592VOID5593SYMCRYPT_CALL5594SymCryptPbkdf2_HmacSha1SelfTest(void);55955596VOID5597SYMCRYPT_CALL5598SymCryptPbkdf2_HmacSha256SelfTest(void);55995600////////////////////////////////////////////////////////////////////////////5601// SP800-108 Counter mode5602//5603// Generic KDF parameter handling:5604// Generic parameter contains the concatenation of the Label, a zero byte, and the Context.5605// To pass a generic parameter do the following:5606// - pbLabel = NULL5607// - cbLabel = (SIZE_T) -1;5608// - pbContext/cbContext = generic parameter5609//56105611SYMCRYPT_ERROR5612SYMCRYPT_CALL5613SymCryptSp800_108ExpandKey(5614_Out_ PSYMCRYPT_SP800_108_EXPANDED_KEY pExpandedKey,5615_In_ PCSYMCRYPT_MAC macAlgorithm,5616_In_reads_(cbKey) PCBYTE pbKey,5617SIZE_T cbKey );56185619SYMCRYPT_ERROR5620SYMCRYPT_CALL5621SymCryptSp800_108Derive(5622_In_ PCSYMCRYPT_SP800_108_EXPANDED_KEY pExpandedKey,5623_In_reads_opt_(cbLabel) PCBYTE pbLabel,5624SIZE_T cbLabel,5625_In_reads_opt_(cbContext) PCBYTE pbContext,5626SIZE_T cbContext,5627_Out_writes_(cbResult) PBYTE pbResult,5628SIZE_T cbResult);56295630SYMCRYPT_ERROR5631SYMCRYPT_CALL5632SymCryptSp800_108(5633PCSYMCRYPT_MAC macAlgorithm,5634_In_reads_(cbKey) PCBYTE pbKey,5635SIZE_T cbKey,5636_In_reads_opt_(cbLabel) PCBYTE pbLabel,5637SIZE_T cbLabel,5638_In_reads_opt_(cbContext) PCBYTE pbContext,5639SIZE_T cbContext,5640_Out_writes_(cbResult) PBYTE pbResult,5641SIZE_T cbResult);56425643VOID5644SYMCRYPT_CALL5645SymCryptSp800_108_HmacSha1SelfTest(void);56465647VOID5648SYMCRYPT_CALL5649SymCryptSp800_108_HmacSha256SelfTest(void);56505651VOID5652SYMCRYPT_CALL5653SymCryptSp800_108_HmacSha384SelfTest(void);56545655VOID5656SYMCRYPT_CALL5657SymCryptSp800_108_HmacSha512SelfTest(void);56585659////////////////////////////////////////////////////////////////////////////5660// TLS Key Derivation PRFs5661//5662// PRFs used in the key derivation functions of the TLS protocol, versions5663// 1.0, 1.1, and 1.2. These are defined in RFC 2246, 4346, and 5246,5664// respectively.5665// Note: The PRFs for versions 1.0 and 1.1 are identical.5666//56675668// Maximum sizes (in bytes) for the label and the seed inputs. See the5669// above RFCs 2246, 4346, and 5246 for more details.5670#define SYMCRYPT_TLS_MAX_LABEL_SIZE 2565671#define SYMCRYPT_TLS_MAX_SEED_SIZE 25656725673//5674// Version 1.0/1.15675//5676SYMCRYPT_ERROR5677SYMCRYPT_CALL5678SymCryptTlsPrf1_1ExpandKey(5679_Out_ PSYMCRYPT_TLSPRF1_1_EXPANDED_KEY pExpandedKey,5680_In_reads_(cbKey) PCBYTE pbKey,5681SIZE_T cbKey);56825683SYMCRYPT_ERROR5684SYMCRYPT_CALL5685SymCryptTlsPrf1_1Derive(5686_In_ PCSYMCRYPT_TLSPRF1_1_EXPANDED_KEY pExpandedKey,5687_In_reads_opt_(cbLabel) PCBYTE pbLabel,5688_In_ SIZE_T cbLabel, // Up to SYMCRYPT_TLS_MAX_LABEL_SIZE5689_In_reads_(cbSeed) PCBYTE pbSeed,5690_In_ SIZE_T cbSeed, // Up to SYMCRYPT_TLS_MAX_SEED_SIZE5691_Out_writes_(cbResult) PBYTE pbResult,5692SIZE_T cbResult);56935694SYMCRYPT_ERROR5695SYMCRYPT_CALL5696SymCryptTlsPrf1_1(5697_In_reads_(cbKey) PCBYTE pbKey,5698_In_ SIZE_T cbKey,5699_In_reads_opt_(cbLabel) PCBYTE pbLabel,5700_In_ SIZE_T cbLabel,5701_In_reads_(cbSeed) PCBYTE pbSeed,5702_In_ SIZE_T cbSeed,5703_Out_writes_(cbResult) PBYTE pbResult,5704SIZE_T cbResult);57055706VOID5707SYMCRYPT_CALL5708SymCryptTlsPrf1_1SelfTest(void);57095710//5711// Version 1.25712//5713SYMCRYPT_ERROR5714SYMCRYPT_CALL5715SymCryptTlsPrf1_2ExpandKey(5716_Out_ PSYMCRYPT_TLSPRF1_2_EXPANDED_KEY pExpandedKey,5717_In_ PCSYMCRYPT_MAC macAlgorithm,5718_In_reads_(cbKey) PCBYTE pbKey,5719SIZE_T cbKey);57205721SYMCRYPT_ERROR5722SYMCRYPT_CALL5723SymCryptTlsPrf1_2Derive(5724_In_ PCSYMCRYPT_TLSPRF1_2_EXPANDED_KEY pExpandedKey,5725_In_reads_opt_(cbLabel) PCBYTE pbLabel,5726_In_ SIZE_T cbLabel, // Up to SYMCRYPT_TLS_MAX_LABEL_SIZE5727_In_reads_(cbSeed) PCBYTE pbSeed,5728_In_ SIZE_T cbSeed, // Up to SYMCRYPT_TLS_MAX_SEED_SIZE5729_Out_writes_(cbResult) PBYTE pbResult,5730SIZE_T cbResult);57315732SYMCRYPT_ERROR5733SYMCRYPT_CALL5734SymCryptTlsPrf1_2(5735_In_ PCSYMCRYPT_MAC macAlgorithm,5736_In_reads_(cbKey) PCBYTE pbKey,5737_In_ SIZE_T cbKey,5738_In_reads_opt_(cbLabel) PCBYTE pbLabel,5739_In_ SIZE_T cbLabel,5740_In_reads_(cbSeed) PCBYTE pbSeed,5741_In_ SIZE_T cbSeed,5742_Out_writes_(cbResult) PBYTE pbResult,5743SIZE_T cbResult);57445745VOID5746SYMCRYPT_CALL5747SymCryptTlsPrf1_2SelfTest(void);574857495750////////////////////////////////////////////////////////////////////////////5751// SSH-KDF as specified in RFC 4253 Section 7.2.5752//575357545755// Labels defined in RFC 42535756#define SYMCRYPT_SSHKDF_IV_CLIENT_TO_SERVER 0x41 // 'A'5757#define SYMCRYPT_SSHKDF_IV_SERVER_TO_CLIENT 0x42 // 'B'5758#define SYMCRYPT_SSHKDF_ENCRYPTION_KEY_CLIENT_TO_SERVER 0x43 // 'C'5759#define SYMCRYPT_SSHKDF_ENCRYPTION_KEY_SERVER_TO_CLIENT 0x44 // 'D'5760#define SYMCRYPT_SSHKDF_INTEGRITY_KEY_CLIENT_TO_SERVER 0x45 // 'E'5761#define SYMCRYPT_SSHKDF_INTEGRITY_KEY_SERVER_TO_CLIENT 0x46 // 'F'576257635764SYMCRYPT_ERROR5765SYMCRYPT_CALL5766SymCryptSshKdfExpandKey(5767_Out_ PSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey,5768_In_ PCSYMCRYPT_HASH pHashFunc,5769_In_reads_(cbKey) PCBYTE pbKey,5770SIZE_T cbKey);5771//5772// Process the key using the specified hash function and store the result in5773// SYMCRYPT_SSHKDF_EXPANDED_KEY structure. Once the key is expanded,5774// SymCryptSshKdfDerive can be called multiple times to generate keys for5775// different uses/labels.5776//5777// After all the keys are derived from a particular "shared secret" key,5778// SYMCRYPT_SSHKDF_EXPANDED_KEY structure must be wiped.5779//5780// Parameters:5781// - pExpandedKey : Pointer to a SYMCRYPT_SSHKDF_EXPANDED_KEY structure that5782// will contain the expanded key after the function returns.5783// - pHashFunc : Hash function that will be used in the key derivation.5784// This function is saved in SYMCRYPT_SSHKDF_EXPANDED_KEY5785// so that it is also used by the SymCryptSshKdfDerive function.5786// - pbKey, cbKey : Buffer containing the secret key for the KDF.5787//5788// Returns SYMCRYPT_NO_ERROR5789//579057915792SYMCRYPT_ERROR5793SYMCRYPT_CALL5794SymCryptSshKdfDerive(5795_In_ PCSYMCRYPT_SSHKDF_EXPANDED_KEY pExpandedKey,5796_In_reads_(cbHashValue) PCBYTE pbHashValue,5797SIZE_T cbHashValue,5798BYTE label,5799_In_reads_(cbSessionId) PCBYTE pbSessionId,5800SIZE_T cbSessionId,5801_Inout_updates_(cbOutput) PBYTE pbOutput,5802SIZE_T cbOutput);5803//5804// Derive keys using the expanded key that was initialized with SymCryptSshKdfExpandKey5805// along with other inputs. This function can be called consecutively with varying label5806// values to generate keys for different purposes as defined in the RFC.5807//5808// Parameters:5809// - pExpandedKey : Pointer to a SYMCRYPT_SSHKDF_EXPANDED_KEY structure that is5810// initialized by a prior call to SymCryptSshKdfExpandKey.5811// Must be wiped when SymCryptSshKdfDerive is not going to be called5812// again with the same expanded key.5813// - pbHashValue, cbHashValue : Buffer pointing to "exchange hash" value. cbHashValue must be equal5814// to the output size of the hash function passed to SymCryptSshKdfExpandKey.5815// - label : Label value used to indicate the type of the derived key.5816// - pbSessionId, cbSessionId : Buffer pointing to the session identifier. cbSessionId must be equal5817// to the output size of the hash function passed to SymCryptSshKdfExpandKey.5818// - pbOutput, cbOutput : Buffer to store the derived key. Exactly cbOutput bytes of output will be generated.5819//5820// Returns SYMCRYPT_NO_ERROR5821//582258235824SYMCRYPT_ERROR5825SYMCRYPT_CALL5826SymCryptSshKdf(5827_In_ PCSYMCRYPT_HASH pHashFunc,5828_In_reads_(cbKey) PCBYTE pbKey,5829SIZE_T cbKey,5830_In_reads_(cbHashValue) PCBYTE pbHashValue,5831SIZE_T cbHashValue,5832BYTE label,5833_In_reads_(cbSessionId) PCBYTE pbSessionId,5834SIZE_T cbSessionId,5835_Out_writes_(cbOutput) PBYTE pbOutput,5836SIZE_T cbOutput);5837//5838// This function is a wrapper for using SymCryptSshKdfExpandKey followed by SymCryptSshKdfDerive5839// in order to produce SSH-KDF output.5840//5841// All of the function arguments are forwarded to SymCryptSshKdfExpandKey and SymCryptSshKdfDerive5842// functions, hence the documentation on those functions apply here as well.5843//584458455846VOID5847SYMCRYPT_CALL5848SymCryptSshKdfSha256SelfTest(void);58495850VOID5851SYMCRYPT_CALL5852SymCryptSshKdfSha512SelfTest(void);585358545855////////////////////////////////////////////////////////////////////////////5856// SRTP-KDF as specified in RFC 3711 Section 4.3.1.5857//585858595860// Labels defined in RFC 37115861#define SYMCRYPT_SRTP_ENCRYPTION_KEY 0x005862#define SYMCRYPT_SRTP_AUTHENTICATION_KEY 0x015863#define SYMCRYPT_SRTP_SALTING_KEY 0x025864#define SYMCRYPT_SRTCP_ENCRYPTION_KEY 0x035865#define SYMCRYPT_SRTCP_AUTHENTICATION_KEY 0x045866#define SYMCRYPT_SRTCP_SALTING_KEY 0x05586758685869SYMCRYPT_ERROR5870SYMCRYPT_CALL5871SymCryptSrtpKdfExpandKey(5872_Out_ PSYMCRYPT_SRTPKDF_EXPANDED_KEY pExpandedKey,5873_In_reads_(cbKey) PCBYTE pbKey,5874SIZE_T cbKey);5875//5876// Process the key and store the result in SYMCRYPT_SRTPKDF_EXPANDED_KEY structure.5877// Once the key is expanded, SymCryptSrtpKdfDerive can be called multiple times to5878// generate keys for different uses/labels.5879//5880// After all the keys are derived from a particular "shared secret" key,5881// SYMCRYPT_SRTPKDF_EXPANDED_KEY structure must be wiped.5882//5883// Parameters:5884// - pExpandedKey : Pointer to a SYMCRYPT_SRTPKDF_EXPANDED_KEY structure that5885// will contain the expanded key after the function returns.5886// - pbKey, cbKey : Buffer containing the secret key for the KDF. cbKey must be5887// a valid AES key size (16-, 24-, or 32-bytes).5888//5889// Returns:5890// SYMCRYPT_WRONG_KEY_SIZE : If cbKey is not a valid AES key size5891// SYMCRYPT_NO_ERROR : On success5892//58935894SYMCRYPT_ERROR5895SYMCRYPT_CALL5896SymCryptSrtpKdfDerive(5897_In_ PCSYMCRYPT_SRTPKDF_EXPANDED_KEY pExpandedKey,5898_In_reads_(cbSalt) PCBYTE pbSalt,5899SIZE_T cbSalt,5900UINT32 uKeyDerivationRate,5901UINT64 uIndex,5902UINT32 uIndexWidth,5903BYTE label,5904_Out_writes_(cbOutput) PBYTE pbOutput,5905SIZE_T cbOutput);5906//5907// Derive keys using the expanded key that was initialized with SymCryptSrtpKdfExpandKey5908// along with other inputs. This function can be called consecutively with varying label5909// values to generate keys for different purposes as defined in the RFC.5910//5911// Parameters:5912// - pExpandedKey : Pointer to a SYMCRYPT_SRTPKDF_EXPANDED_KEY structure that is5913// initialized by a prior call to SymCryptSrtpKdfExpandKey.5914// Must be wiped when SymCryptSrtpKdfDerive is not going to be called5915// again with the same expanded key.5916// - pbSalt, cbSalt : Buffer pointing to the salt value. cbSalt must always be 14 (112-bits).5917// - uKeyDerivationRate : Key derivation rate; must be zero or 2^i for 0 <= i <= 24.5918// - uIndex : Denotes an SRTP index value when label is 0x00, 0x01, or 0x02, otherwise5919// denotes an SRTCP index value.5920// - uIndexWidth : Denotes how wide uIndex value is. Must be one of 0, 32, or 48. By default,5921// (when uIndexWidth = 0) uIndex is treated as 48-bits.5922// RFC 3711 initially defined SRTCP indices to be 32-bit values. It was updated5923// to be 48-bits by Errata ID 3712. SRTP index values are defined to be 48-bits.5924// - label : Label value used to indicate the type of the derived key.5925// - pbOutput, cbOutput : Buffer to store the derived key. Exactly cbOutput bytes of output will be generated.5926//5927// Returns:5928// SYMCRYPT_INVALID_ARGUMENT : If cbSalt is not 14-bytes, or uKeyDerivationRate in invalid.5929// SYMCRYPT_NO_ERROR : On success.5930//593159325933SYMCRYPT_ERROR5934SYMCRYPT_CALL5935SymCryptSrtpKdf(5936_In_reads_(cbKey) PCBYTE pbKey,5937SIZE_T cbKey,5938_In_reads_(cbSalt) PCBYTE pbSalt,5939SIZE_T cbSalt,5940UINT32 uKeyDerivationRate,5941UINT64 uIndex,5942UINT32 uIndexWidth,5943BYTE label,5944_Out_writes_(cbOutput) PBYTE pbOutput,5945SIZE_T cbOutput);5946//5947// This function is a wrapper for using SymCryptSrtpKdfExpandKey followed by SymCryptSrtpKdfDerive5948// in order to produce SRTP-KDF output.5949//5950// All of the function arguments are forwarded to SymCryptSrtpKdfExpandKey and SymCryptSrtpKdfDerive5951// functions, hence the documentation on those functions apply here as well.5952//595359545955VOID5956SYMCRYPT_CALL5957SymCryptSrtpKdfSelfTest(void);595859595960////////////////////////////////////////////////////////////////////////////5961// HKDF5962//5963// PRF used in the key derivation functions of the TLS protocol, version5964// 1.3. It is defined in RFC 5869.5965//5966// The SymCrypt ExtractPrk function corresponds to the "HKDF-Extract" function5967// of the RFC 5869, while the SymCrypt PrkExpandKey and Derive functions5968// correspond to the "HKDF-Expand" function of the RFC.5969//5970// SymCryptHkdfExtractPrk takes as inputs the MAC algorithm, the IKM (input5971// keying material), and the optional salt. It executes the full "HKDF-Extract"5972// function to produce the PRK (pseudorandom key).5973//5974// SymCryptHkdfPrkExpandKey takes as inputs just the MAC algorithm and the PRK.5975// It produces the final (MAC) key to be used by the "HKDF-Expand" function.5976//5977// SymCryptHkdfExpandKey performs SymCryptHkdfExtractPrk followed by5978// SymCryptHkdfPrkExpandKey to produce the final (MAC) key to be used by the5979// "HKDF-Expand" function, without exposing the PRK to the caller.5980//5981// SymCryptHkdfDerive takes as input the final MAC key and the optional info. It5982// performs the rest of the "HKDF-Expand" function to produce the HKDF result.5983//59845985SYMCRYPT_ERROR5986SYMCRYPT_CALL5987SymCryptHkdfExpandKey(5988_Out_ PSYMCRYPT_HKDF_EXPANDED_KEY pExpandedKey,5989_In_ PCSYMCRYPT_MAC macAlgorithm,5990_In_reads_(cbIkm) PCBYTE pbIkm,5991SIZE_T cbIkm,5992_In_reads_opt_(cbSalt) PCBYTE pbSalt,5993SIZE_T cbSalt );59945995SYMCRYPT_ERROR5996SYMCRYPT_CALL5997SymCryptHkdfExtractPrk(5998_In_ PCSYMCRYPT_MAC macAlgorithm,5999_In_reads_(cbIkm) PCBYTE pbIkm,6000SIZE_T cbIkm,6001_In_reads_opt_(cbSalt) PCBYTE pbSalt,6002SIZE_T cbSalt,6003_Out_writes_(cbPrk) PBYTE pbPrk,6004SIZE_T cbPrk );60056006SYMCRYPT_ERROR6007SYMCRYPT_CALL6008SymCryptHkdfPrkExpandKey(6009_Out_ PSYMCRYPT_HKDF_EXPANDED_KEY pExpandedKey,6010_In_ PCSYMCRYPT_MAC macAlgorithm,6011_In_reads_(cbPrk) PCBYTE pbPrk,6012SIZE_T cbPrk );60136014SYMCRYPT_ERROR6015SYMCRYPT_CALL6016SymCryptHkdfDerive(6017_In_ PCSYMCRYPT_HKDF_EXPANDED_KEY pExpandedKey,6018_In_reads_opt_(cbInfo) PCBYTE pbInfo,6019SIZE_T cbInfo,6020_Out_writes_(cbResult) PBYTE pbResult,6021SIZE_T cbResult);60226023SYMCRYPT_ERROR6024SYMCRYPT_CALL6025SymCryptHkdf(6026PCSYMCRYPT_MAC macAlgorithm,6027_In_reads_(cbIkm) PCBYTE pbIkm,6028SIZE_T cbIkm,6029_In_reads_opt_(cbSalt) PCBYTE pbSalt,6030SIZE_T cbSalt,6031_In_reads_opt_(cbInfo) PCBYTE pbInfo,6032SIZE_T cbInfo,6033_Out_writes_(cbResult) PBYTE pbResult,6034SIZE_T cbResult);60356036VOID6037SYMCRYPT_CALL6038SymCryptHkdfSelfTest(void);60396040////////////////////////////////////////////////////////////////////////////6041// SSKDF6042//6043// Single-Step KDF as specified in SP800-56C section 4.6044//6045// SSKDF requires an auxiliary function H. This can be approved hash function,6046// HMAC with an approved hash function, or KMAC. The approved hash functions6047// are listed in SP800-56C section 7.6048//6049// A salt value may be optionally provided if either HMAC or KMAC is used for H.6050// When no salt is provided, an all-zero default salt is used instead. For HMAC,6051// the default salt is the length of an input block of the HMAC's hash function.6052// For KMAC128, the default salt is 164 bytes. For KMAC256, the default salt is 132 bytes.6053//60546055SYMCRYPT_ERROR6056SYMCRYPT_CALL6057SymCryptSskdfMacExpandSalt(6058_Out_ PSYMCRYPT_SSKDF_MAC_EXPANDED_SALT pExpandedSalt,6059_In_ PCSYMCRYPT_MAC macAlgorithm,6060_In_reads_opt_(cbSalt) PCBYTE pbSalt,6061SIZE_T cbSalt);6062//6063// Initializes *pExpandedSalt with the macAlgorithm, and optionally the salt. Used6064// for SSKDF when H is a MAC function. After calling SymCryptSskdfMacExpandSalt,6065// SymCryptSskdfMacDerive can be called multiple times to generate keys for different6066// uses, fixed infos, and shared secrets. For multiple KDFs using the same MAC and salt,6067// calling SymCryptSskdfMacExpandSalt once and SymCryptSskdfMacDerive multiple times6068// is more efficient than calling SymCryptSskdfMac multiple times.6069//6070// The expanded salt contains no secrets and does not need to be wiped.6071//6072// Parameters:6073// - pExpandedSalt : Pointer to a SYMCRYPT_SSKDF_MAC_EXPANDED_SALT structure that6074// will contain the expanded salt after the function returns.6075// - macAlgorithm : MAC algorithm that will be used in the key derivation.6076// This function is saved in SYMCRYPT_SSKDF_MAC_EXPANDED_SALT.6077// - pbSalt, cbSalt : Buffer containing the salt for the KDF. cbSalt must be a valid6078// key size for the MAC algorithm. If pbSalt is NULL, the default6079// all zero-byte salt is used.6080//60816082SYMCRYPT_ERROR6083SYMCRYPT_CALL6084SymCryptSskdfMacDerive(6085_In_ PCSYMCRYPT_SSKDF_MAC_EXPANDED_SALT pExpandedSalt,6086SIZE_T cbMacOutputSize,6087_In_reads_(cbSecret) PCBYTE pbSecret,6088SIZE_T cbSecret,6089_In_reads_opt_(cbInfo) PCBYTE pbInfo,6090SIZE_T cbInfo,6091_Out_writes_(cbResult) PBYTE pbResult,6092SIZE_T cbResult);6093//6094// Derive keys using the expanded salt that was initialized with SymCryptSskdfMacExpandSalt6095// along with other inputs. This function can be called consecutively with varying fixed infos6096// and shared secrets to generate keys for different purposes as defined in the SP800-56C.6097// The same pbExpandedKey can be used simultaneously by multiple threads.6098//6099// Parameters:6100// - pExpandedSalt : Pointer to a SYMCRYPT_SSKDF_MAC_EXPANDED_SALT structure that is6101// initialized by a prior call to SymCryptSskdfMacExpandSalt.6102// - cbMacOutputSize : Output size used by the MAC algorithm for intermediate computations. Must not be6103// greater than 64 bytes. Set to 0 for MACs that don't support variable output sizes,6104// or to use the default output size. The default output size when KMAC is used is cbResult.6105// - pbSecret, cbSecret : Buffer containing the shared secret.6106// - pbInfo, cbInfo : Buffer containing the fixed info.6107// - pbResult, cbResult : Buffer to store the derived key. Exactly cbResult bytes of output will be generated.6108// Must not exceed 2^{32} - 1 times the result size of the MAC algorithm.6109//61106111SYMCRYPT_ERROR6112SYMCRYPT_CALL6113SymCryptSskdfMac(6114_In_ PCSYMCRYPT_MAC macAlgorithm,6115SIZE_T cbMacOutputSize,6116_In_reads_(cbSecret) PCBYTE pbSecret,6117SIZE_T cbSecret,6118_In_reads_opt_(cbSalt) PCBYTE pbSalt,6119SIZE_T cbSalt,6120_In_reads_opt_(cbInfo) PCBYTE pbInfo,6121SIZE_T cbInfo,6122_Out_writes_(cbResult) PBYTE pbResult,6123SIZE_T cbResult);6124//6125// This function is a wrapper for using SymCryptSskdfMacExpandSalt followed by SymCryptSskdfMacDerive6126// in order to produce SSKDF output.6127//6128// All of the function arguments are forwarded to SymCryptSskdfMacExpandSalt and SymCryptSskdfMacDerive6129// functions, hence the documentation on those functions apply here as well.6130//61316132SYMCRYPT_ERROR6133SYMCRYPT_CALL6134SymCryptSskdfHash(6135_In_ PCSYMCRYPT_HASH hashAlgorithm,6136SIZE_T cbHashOutputSize,6137_In_reads_(cbSecret) PCBYTE pbSecret,6138SIZE_T cbSecret,6139_In_reads_opt_(cbInfo) PCBYTE pbInfo,6140SIZE_T cbInfo,6141_Out_writes_(cbResult) PBYTE pbResult,6142SIZE_T cbResult);6143//6144// Derive keys using the specified hash algorithm as H.6145//6146// Parameters:6147// - hashAlgorithm : Hash algorithm that will be used in the key derivation.6148// - cbHashOutputSize : Output size used by the hash algorithm for intermediate computations.6149// Set to 0 for hashes that don't support variable output sizes, or to use6150// the default output size. Currently, no allowed hash algorithms support6151// variable output sizes, so this should always be set to 0.6152// - pbSecret, cbSecret : Buffer containing the shared secret.6153// - pbInfo, cbInfo : Buffer containing the fixed info.6154// - pbResult, cbResult : Buffer to store the derived key. Exactly cbResult bytes of output will be generated.6155// Must not exceed 2^{32} - 1 times the result size of hashAlgorithm.6156//61576158VOID6159SYMCRYPT_CALL6160SymCryptSskdfSelfTest(void);61616162//==========================================================================6163// RNG ALGORITHMS6164//==========================================================================61656166////////////////////////////////////////////////////////////////////////////6167// AES-CTR-DRBG6168//6169// This is an implementation of AES-CTR_DRBG as specified in SP 800-90.6170// It always uses a 256-bit security strength.6171//6172// Note: This RNG is NOT compliant with FIPS 140-2 as it lacks the continuous6173// self test required by FIPS 140-2. See the AES-FIPS RNG algorithm below.6174//6175// SYMCRYPT_RNG_AES_STATE6176// State of an AES-CTR_DRBG instance.6177//61786179#define SYMCRYPT_RNG_AES_MIN_INSTANTIATE_SIZE (32 + 16)6180#define SYMCRYPT_RNG_AES_MIN_RESEED_SIZE (32)6181#define SYMCRYPT_RNG_AES_MAX_SEED_SIZE (256)61826183SYMCRYPT_ERROR6184SYMCRYPT_CALL6185SymCryptRngAesInstantiate(6186_Out_ PSYMCRYPT_RNG_AES_STATE pRngState,6187_In_reads_(cbSeedMaterial) PCBYTE pcbSeedMaterial,61886189_In_range_(SYMCRYPT_RNG_AES_MIN_INSTANTIATE_SIZE, SYMCRYPT_RNG_AES_MAX_SEED_SIZE)6190SIZE_T cbSeedMaterial );6191//6192// Initialize a new SYMCRYPT_RNG_AES_STATE, and seed it with the seed material.6193//6194// 'Instantiate' is the SP800-90 terminology.6195// The seed material must be at least SYMCRYPT_RNG_AES_MIN_INSTANTIATE_SIZE bytes,6196// and at most SYMCRYPT_RNG_AES_MAX_SEED_SIZE bytes.6197//6198// This implementation always uses 256-bit security strength, and6199// does not support 'prediction resistance' as defined in SP 800-90.6200//6201// SP 800-90 specifies three inputs to the instantiation:6202// - entropy6203// - nonce6204// - personalization string6205// This function takes only a single input, which is the concatenation of these three:6206// seed material := entropy | nonce | personalization string6207//6208// The following are the requirements on the three inputs:6209// Entropy: must have at least 256 bits of entropy6210// Nonce: must either be a random value with 128-bits of entropy, or a value that does not6211// repeat with a probability of more than 2^{-128}.6212// Together these requirements imply that cbSeedMaterial should be at least6213// SYMCRYPT_RNG_AES_MIN_INSTANTIATE_SIZE6214//6215// This function only returns an error if the cbSeedMaterial value is out of range.6216//62176218VOID6219SYMCRYPT_CALL6220SymCryptRngAesGenerate(6221_Inout_ PSYMCRYPT_RNG_AES_STATE pRngState,6222_Out_writes_(cbRandom) PBYTE pbRandom,6223SIZE_T cbRandom );6224//6225// Generate random output from the state.6226//6227// Callers do not need to limit themselves to requests of 64 kB or less;6228// large requests are split internally to follow the request size limitations of SP 800-90.6229//6230// SP 800-90 also requires a limit on the # generate calls that can be done between reseeds.6231// For AES-CTR_DRBG this limit is 2^48, which means it is all but impossible to hit this limit.6232// If the caller were to succeed, the 2^48'th call will result in a fatal error.6233//62346235SYMCRYPT_ERROR6236SYMCRYPT_CALL6237SymCryptRngAesReseed(6238_Inout_ PSYMCRYPT_RNG_AES_STATE pRngState,6239_In_reads_(cbSeedMaterial) PCBYTE pcbSeedMaterial,62406241_In_range_(SYMCRYPT_RNG_AES_MIN_RESEED_SIZE, SYMCRYPT_RNG_AES_MAX_SEED_SIZE)6242SIZE_T cbSeedMaterial );6243//6244// Reseed the PRNG state.6245//6246// The seed material consists of the concatenation of the following SP800-90 fields:6247// - entropy6248// - additional input6249//6250// The entropy input should have at least 256 bits of entropy.6251// This function only returns an error if the cbSeedMaterial value is out of range.6252//62536254VOID6255SYMCRYPT_CALL6256SymCryptRngAesUninstantiate(6257_Inout_ PSYMCRYPT_RNG_AES_STATE pRngState );6258//6259// Uninstantiate (clean up) the PRNG state6260//62616262VOID6263SYMCRYPT_CALL6264SymCryptRngAesInstantiateSelftest(void);6265//6266// For FIPS-certified modules, this function should be called before every instantiation.6267// If multiple DRBGs are instantiated 'in quick succession', a single self-test is sufficient6268// (see SP 800-90 11.3.2).6269//627062716272VOID6273SYMCRYPT_CALL6274SymCryptRngAesReseedSelftest(void);6275//6276// FIPS-certified modules should call this function before every call to the reseed function.6277//62786279VOID6280SYMCRYPT_CALL6281SymCryptRngAesGenerateSelftest(void);6282//6283// FIPS-certified modules should call this function at least once on startup, and whenever6284// they want to re-test the generate function.6285//62866287////////////////////////////////////////////////////////////////////////////6288// AES-CTR-DRBG with FIPS 140-2 continuous self-test6289//6290// This is a straightforward wrapper around the AES-CTR-DRBG implementation6291// that adds the FIPS 140-2 continuous self-test.6292// At the moment, it looks like this test will not be present in FIPS 140-3 so6293// this RNG will be dropped when FIPS 140-3 comes out.6294// The self-test requirements are met by calling the selftest functions of the6295// AES-CTR_DRBG implementation directly.6296//6297// These functions are functionally equivalent to the ones for AES-CTR_DRBG.6298//62996300SYMCRYPT_ERROR6301SYMCRYPT_CALL6302SymCryptRngAesFips140_2Instantiate(6303_Out_ PSYMCRYPT_RNG_AES_FIPS140_2_STATE pRngState,6304_In_reads_(cbSeedMaterial) PCBYTE pcbSeedMaterial,63056306_In_range_(SYMCRYPT_RNG_AES_MIN_INSTANTIATE_SIZE, SYMCRYPT_RNG_AES_MAX_SEED_SIZE)6307SIZE_T cbSeedMaterial );63086309VOID6310SYMCRYPT_CALL6311SymCryptRngAesFips140_2Generate(6312_Inout_ PSYMCRYPT_RNG_AES_FIPS140_2_STATE pRngState,6313_Out_writes_(cbRandom) PBYTE pbRandom,6314SIZE_T cbRandom );63156316SYMCRYPT_ERROR6317SYMCRYPT_CALL6318SymCryptRngAesFips140_2Reseed(6319_Inout_ PSYMCRYPT_RNG_AES_FIPS140_2_STATE pRngState,6320_In_reads_(cbSeedMaterial) PCBYTE pcbSeedMaterial,63216322_In_range_(SYMCRYPT_RNG_AES_MIN_RESEED_SIZE, SYMCRYPT_RNG_AES_MAX_SEED_SIZE)6323SIZE_T cbSeedMaterial );63246325VOID6326SYMCRYPT_CALL6327SymCryptRngAesFips140_2Uninstantiate(6328_Inout_ PSYMCRYPT_RNG_AES_FIPS140_2_STATE pRngState );63296330////////////////////////////////////////////////////////////////////////////////////////////6331//6332// Internal RNG functions6333//6334// To satisfy FIPS 140-3 and SP 800-90B, certain modules of SymCrypt may set up internal6335// RNG state(s) to keep random bit generation behind the module's FIPS boundary.6336// These functions allow the caller to get random bits and provide entropy, respectively,6337// to SymCrypt's internal RNG state(s).6338// Implementation is module dependent, and these functions may not be defined6339// for certain modules. Check before using.6340//63416342VOID6343SYMCRYPT_CALL6344SymCryptRandom(6345_Out_writes_(cbRandom) PBYTE pbRandom,6346SIZE_T cbRandom );6347// Fills pbRandom with cbRandom random bytes63486349VOID6350SYMCRYPT_CALL6351SymCryptProvideEntropy(6352_In_reads_(cbEntropy) PCBYTE pbEntropy,6353SIZE_T cbEntropy );6354// Mixes pbEntropy into the internal RNG state. There may be module-specific limits on6355// cbEntropy - check module before use635663576358////////////////////////////////////////////////////////////////////////////////////////////6359//6360// RdRand support6361// These functions provide access to the RdRand random number generator in6362// the latest Intel CPUs.6363// The DRBG that underlies the RdRand instruction is limited to 128-bit security.6364// The seed for each consecutive 8 kB of data can be recovered in 2^128 work.6365// Therefore, we allow for multiple blocks of 8 kB to be gathered in an attempt to6366// extract 256-bit security from the hardware.6367// In general, to achieve N*128 bits of security, you should use a buffer of6368// (N+1)*SYMCRYPT_RDRAND_RESEED_SIZE bytes.6369//63706371#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD6463726373// The RdRand instruction reseeds its internal DRBG every 8 kB (or faster)6374#define SYMCRYPT_RDRAND_RESEED_SIZE (1<<13)63756376SYMCRYPT_ERROR6377SYMCRYPT_CALL6378SymCryptRdrandStatus(void);6379//6380// Returns SYMCRYPT_NO_ERROR if RdRand is available.6381// returns SYMCRYPT_NOT_IMPLEMENTED if RdRand is not available.6382// Note: the library must be initialized before you call this function.6383//638463856386SYMCRYPT_ERROR6387SYMCRYPT_CALL6388SymCryptRdrandGetBytes(6389_Out_writes_( cbBuffer ) PBYTE pbBuffer,6390SIZE_T cbBuffer,6391_Out_writes_( SYMCRYPT_SHA512_RESULT_SIZE ) PBYTE pbResult );6392//6393// Gets cbBuffer bytes from the RdRand instruction and hashes them to the pbResult buffer.6394// pbBuffer points to a scratch buffer that is used internally, but wiped upon exit.6395// cbBuffer must be a multiple of 16.6396// Fatal error if SymCryptRdrandStatus indicates that Rdrand is not available.6397// Returns an error if the RdRand instruction failed consistently.6398// Note: SymCrypt only checks whether RdRand self-reports as failing. SymCrypt does NOT attempt6399// to validate that the values returned in successful RdRand calls are in fact random.6400// See SymCryptRdrandGet for a version that does not return an error but fatals instead.6401//64026403VOID6404SYMCRYPT_CALL6405SymCryptRdrandGet(6406_Out_writes_( cbBuffer ) PBYTE pbBuffer,6407SIZE_T cbBuffer,6408_Out_writes_( SYMCRYPT_SHA512_RESULT_SIZE ) PBYTE pbResult );6409//6410// Gets cbBuffer bytes from the RdRand instruction and hashes them to the pbResult buffer.6411// pbBuffer points to a scratch buffer that is used internally, but wiped upon exit.6412// cbBuffer must be a multiple of 16.6413// Fatal error if the RdRand instruction fails.6414// Note: SymCrypt only checks whether RdRand self-reports as failing. SymCrypt does NOT attempt6415// to validate that the values returned in successful RdRand calls are in fact random.6416//64176418#endif641964206421////////////////////////////////////////////////////////////////////////////////////////////6422//6423// RdSeed support6424// These functions provide access to the RdSeed random number generator in6425// recent Intel CPUs.6426//64276428#if SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_AMD6464296430SYMCRYPT_ERROR6431SYMCRYPT_CALL6432SymCryptRdseedStatus(void);6433//6434// Returns SYMCRYPT_NO_ERROR if RdSeed is available.6435// returns SYMCRYPT_NOT_IMPLEMENTED if RdSeed is not available.6436// Note: the library must be initialized before you call this function.6437//643864396440SYMCRYPT_ERROR6441SYMCRYPT_CALL6442SymCryptRdseedGetBytes(6443_Out_writes_( cbResult ) PBYTE pbResult,6444SIZE_T cbResult );6445//6446// Queries cbResult bytes from the Rdseed instruction and puts them in the buffer.6447// The number of bytes (cbResult) must be a multiple of 16.6448// Fatal error if the Rdseed instruction is not present.6449// Returns an error if the Rdseed instruction fails consistently.6450// Note: SymCrypt only checks whether Rdseed self-reports as failing. SymCrypt does NOT attempt6451// to validate that the values returned in successful Rdseed calls are in fact random.6452// See SymCryptRdseedGet for a version that does not return an error but fatals instead.6453//64546455VOID6456SYMCRYPT_CALL6457SymCryptRdseedGet(6458_Out_writes_( cbResult ) PBYTE pbResult,6459SIZE_T cbResult );6460//6461// Queries cbResult bytes from the Rdseed instruction and puts them in the buffer.6462// The number of bytes (cbResult) must be a multiple of 16.6463// Fatal error if the Rdseed instruction is not present, or the instruction fails consistently.6464// Note: SymCrypt only checks whether Rdseed self-reports as failing. SymCrypt does NOT attempt6465// to validate that the values returned in successful Rdseed calls are in fact random.6466//64676468#endif64696470////////////////////////////////////////////////////////////////////////////////////////////6471//6472// AES-XTS6473//64746475SYMCRYPT_ERROR6476SYMCRYPT_CALL6477SymCryptXtsAesExpandKey(6478_Out_ PSYMCRYPT_XTS_AES_EXPANDED_KEY pExpandedKey,6479_In_reads_( cbKey ) PCBYTE pbKey,6480SIZE_T cbKey );6481// Note that this key expansion function does not perform FIPS checks for backwards compatibility.6482// Use SymCryptXtsAesExpandKeyEx for FIPS-approved XTS key expansion.64836484SYMCRYPT_ERROR6485SYMCRYPT_CALL6486SymCryptXtsAesExpandKeyEx(6487_Out_ PSYMCRYPT_XTS_AES_EXPANDED_KEY pExpandedKey,6488_In_reads_( cbKey ) PCBYTE pbKey,6489SIZE_T cbKey,6490UINT32 flags );6491// Allowed flags:6492//6493// - SYMCRYPT_FLAG_KEY_NO_FIPS6494// Opt-out of performing validation required for FIPS.6495// Currently this is just checking that 2 AES keys used in XTS are non-equal.64966497VOID6498SYMCRYPT_CALL6499SymCryptXtsAesKeyCopy(6500_In_ PCSYMCRYPT_XTS_AES_EXPANDED_KEY pSrc,6501_Out_ PSYMCRYPT_XTS_AES_EXPANDED_KEY pDst );6502//6503// Create a copy of an expanded key6504//65056506VOID6507SYMCRYPT_CALL6508SymCryptXtsAesEncrypt(6509_In_ PCSYMCRYPT_XTS_AES_EXPANDED_KEY pExpandedKey,6510SIZE_T cbDataUnit,6511UINT64 tweak,6512_In_reads_( cbData ) PCBYTE pbSrc,6513_Out_writes_( cbData ) PBYTE pbDst,6514SIZE_T cbData );6515//6516// Encrypt a buffer using XTS-AES and 64 bit tweak.6517// - pExpandedKey points to the expanded key for XTS.6518// - cbDataUnit: size of each data unit, must be at least 16 and cannot exceed 2^{24} bytes. Typically 512.6519// - tweak: 64 bit tweak value used for the first data unit in the buffer, incremented for subsequent data units.6520// - pbSrc: plaintext input6521// - pbDst: ciphertext output. The ciphertext buffer may be identical to the plaintext6522// buffer, or non-overlapping. The ciphertext is also cbData bytes long.6523// - cbData: # bytes of plaintext input. Must be a multiple of cbDataUnit.6524//6525// XTS-AES works on equal-sized data units, with each data unit being uniquely encrypted using a combination of6526// an integer "tweak" value and the XTS key (a pair of AES keys). A data unit typically corresponds to a sector6527// size on a disk.6528//6529// This API encrypts a buffer consisting of several consecutive data units, which use consecutive tweak values.6530// As the tweak is 64 bits, if there is an overflow of 64 bits, the value of the tweak will wrap to 0.6531//6532// i.e. encryption with tweak 0xffffffffffffffff for a buffer consisting of 2 data units will correspond to:6533// encryption using tweak 0xffffffffffffffff for the first data unit,6534// encryption using tweak 0x0000000000000000 for the second data unit6535//6536// Note, using cbDataUnit which is a power of 2 >= 256, will likely be more performant.6537//65386539VOID6540SYMCRYPT_CALL6541SymCryptXtsAesDecrypt(6542_In_ PCSYMCRYPT_XTS_AES_EXPANDED_KEY pExpandedKey,6543SIZE_T cbDataUnit,6544UINT64 tweak,6545_In_reads_( cbData ) PCBYTE pbSrc,6546_Out_writes_( cbData ) PBYTE pbDst,6547SIZE_T cbData );6548//6549// Decrypt a buffer using XTS-AES and 64 bit tweak.6550// See SymCryptXtsAesEncrypt for a more in depth description, everything is the same, only this decrypts rather than encrypts.6551//65526553VOID6554SYMCRYPT_CALL6555SymCryptXtsAesEncryptWith128bTweak(6556_In_ PCSYMCRYPT_XTS_AES_EXPANDED_KEY pExpandedKey,6557SIZE_T cbDataUnit,6558_In_reads_( SYMCRYPT_AES_BLOCK_SIZE ) PCBYTE pbTweak,6559_In_reads_( cbData ) PCBYTE pbSrc,6560_Out_writes_( cbData ) PBYTE pbDst,6561SIZE_T cbData );6562//6563// Encrypt a buffer using XTS-AES and 128 bit tweak.6564// - pExpandedKey points to the expanded key for XTS.6565// - cbDataUnit: size of each data unit, must be at least 16 and cannot exceed 2^{24} bytes. Typically 512.6566// - pbTweak: 128 bit tweak value used for the first data unit in the buffer, incremented for subsequent data units.6567// - pbSrc: plaintext input6568// - pbDst: ciphertext output. The ciphertext buffer may be identical to the plaintext6569// buffer, or non-overlapping. The ciphertext is also cbData bytes long.6570// - cbData: # bytes of plaintext input. Must be a multiple of cbDataUnit.6571//6572// XTS-AES works on equal-sized data units, with each data unit being uniquely encrypted using a combination of6573// an integer "tweak" value and the XTS key (a pair of AES keys). A data unit typically corresponds to a sector6574// size on a disk.6575//6576// This API encrypts a buffer consisting of several consecutive data units, which use consecutive tweak values.6577// As the tweak is 128 bits, if there is an overflow of 128 bits, the value of the tweak will wrap to 0.6578//6579// i.e. encryption with tweak 0x0000000000000000ffffffffffffffff for a buffer consisting of 2 data units will correspond to:6580// encryption using tweak 0x0000000000000000ffffffffffffffff for the first data unit,6581// encryption using tweak 0x00000000000000010000000000000000 for the second data unit6582// but encryption with tweak 0xffffffffffffffffffffffffffffffff for a buffer consisting of 2 data units will correspond to:6583// encryption using tweak 0xffffffffffffffffffffffffffffffff for the first data unit,6584// encryption using tweak 0x00000000000000000000000000000000 for the second data unit6585//6586// Note, using cbDataUnit which is a power of 2 >= 256, will likely be more performant.6587//65886589VOID6590SYMCRYPT_CALL6591SymCryptXtsAesDecryptWith128bTweak(6592_In_ PCSYMCRYPT_XTS_AES_EXPANDED_KEY pExpandedKey,6593SIZE_T cbDataUnit,6594_In_reads_( SYMCRYPT_AES_BLOCK_SIZE ) PCBYTE pbTweak,6595_In_reads_( cbData ) PCBYTE pbSrc,6596_Out_writes_( cbData ) PBYTE pbDst,6597SIZE_T cbData );6598//6599// Decrypt a buffer using XTS-AES and 128 bit tweak.6600// See SymCryptXtsAesEncryptWith128bTweak for a more in depth description, everything is the same, only this decrypts rather than encrypts.6601//66026603VOID6604SYMCRYPT_CALL6605SymCryptXtsAesSelftest(void);66066607////////////////////////////////////////////////////////////////////////////////////////////6608//6609// AES-KW and AES-KWP6610//6611// These are the AES-KW and AES-KWP algorithms per SP 800-38F.6612//6613// These are very slow compared to most AES modes, requiring a long serial chain of AES6614// block encryption/decryptions, with a best case cost comparable to ~12x AES-CBC encryption6615// for a given buffer size. In practice the cost is often higher.6616// These cipher modes are not recommended.6617//66186619SYMCRYPT_ERROR6620SYMCRYPT_CALL6621SymCryptAesKwEncrypt(6622_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,6623_In_reads_(cbSrc) PCBYTE pbSrc,6624SIZE_T cbSrc,6625_Out_writes_to_(cbDst, *pcbResult) PBYTE pbDst,6626SIZE_T cbDst,6627_Out_ SIZE_T* pcbResult );6628//6629// Encrypt a buffer using AES-KW mode.6630//6631// - pExpandedKey points to the expanded key to use.6632// - pbSrc is the plaintext source buffer. The source and destination buffers may be6633// identical (in-place encryption) or non-overlapping, but they may not partially overlap.6634// - cbSrc. # bytes of plaintext. This must be a multiple of 8, >=16, and <2^31.6635// - pbDst is the ciphertext destination buffer. The source and destination buffers may be6636// identical (in-place encryption) or non-overlapping, but they may not partially overlap.6637// - cbDst. # bytes in the destination buffer. This must be >= cbSrc+8.6638// - pcbResult pointer to a variable which receives the length of the ciphertext written to pbDst.6639//6640// Returns:6641// SYMCRYPT_INVALID_ARGUMENT : If cbSrc is an invalid size6642// SYMCRYPT_BUFFER_TOO_SMALL : If cbDst is not large enough6643// (this can always be avoided if cbDst >= cbSrc+8)6644// SYMCRYPT_MEMORY_ALLOCATION_FAILURE : If there is insufficient memory for the operation6645// SYMCRYPT_NO_ERROR : On success6646//6647// Remarks:6648// The standard allows larger plaintexts but there is no requirement to support them, we only support6649// plaintext up to 2^31 bytes because it avoids complexity in handling overflow of 32b buffer sizes, and6650// is larger than practically necessary.6651// The output parameters (pbDst and pcbResult) are only set on success.6652//66536654SYMCRYPT_ERROR6655SYMCRYPT_CALL6656SymCryptAesKwDecrypt(6657_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,6658_In_reads_(cbSrc) PCBYTE pbSrc,6659SIZE_T cbSrc,6660_Out_writes_to_(cbDst, *pcbResult) PBYTE pbDst,6661SIZE_T cbDst,6662_Out_ SIZE_T* pcbResult );6663//6664// Decrypt a buffer using AES-KW mode.6665//6666// - pExpandedKey points to the expanded key to use.6667// - pbSrc is the ciphertext source buffer. The source and destination buffers may be6668// identical (in-place decryption) or non-overlapping, but they may not partially overlap.6669// - cbSrc. # bytes of ciphertext. This must be a multiple of 8, >=24, and <=2^31.6670// - pbDst is the plaintext destination buffer. The source and destination buffers may be6671// identical (in-place decryption) or non-overlapping, but they may not partially overlap.6672// - cbDst. # bytes in the destination buffer. This must be >= cbSrc-8.6673// - pcbResult pointer to a variable which receives the length of the plaintext written to pbDst.6674//6675// Returns:6676// SYMCRYPT_INVALID_ARGUMENT : If cbSrc is an invalid size6677// SYMCRYPT_BUFFER_TOO_SMALL : If cbDst is not large enough6678// (this can always be avoided if cbDst >= cbSrc-8)6679// SYMCRYPT_AUTHENTICATION_FAILURE : If pbSrc does not decrypt successfully6680// SYMCRYPT_MEMORY_ALLOCATION_FAILURE : If there is insufficient memory for the operation6681// SYMCRYPT_NO_ERROR : On success6682//6683// Remarks:6684// The standard allows larger plaintexts but there is no requirement to support them, we only support6685// plaintext up to 2^31 bytes because it avoids complexity in handling overflow of 32b buffer sizes, and6686// is larger than practically necessary.6687// The output parameters (pbDst and pcbResult) are only set on success.6688//66896690SYMCRYPT_ERROR6691SYMCRYPT_CALL6692SymCryptAesKwpEncrypt(6693_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,6694_In_reads_(cbSrc) PCBYTE pbSrc,6695SIZE_T cbSrc,6696_Out_writes_to_(cbDst, *pcbResult) PBYTE pbDst,6697SIZE_T cbDst,6698_Out_ SIZE_T* pcbResult );6699//6700// Encrypt a buffer using AES-KWP mode.6701//6702// - pExpandedKey points to the expanded key to use.6703// - pbSrc is the plaintext source buffer. The source and destination buffers may be6704// identical (in-place encryption) or non-overlapping, but they may not partially overlap.6705// - cbSrc. # bytes of plaintext. This must be >0 and <=2^31-8.6706// - pbDst is the ciphertext destination buffer. The source and destination buffers may be6707// identical (in-place encryption) or non-overlapping, but they may not partially overlap.6708// - cbDst. # bytes in the destination buffer. This must be >= cbSrc + 16 - (cbSrc%8) - ((cbSrc%8)==0 ? 8 : 0)6709// - pcbResult pointer to a variable which receives the length of the ciphertext written to pbDst.6710//6711// Returns:6712// SYMCRYPT_INVALID_ARGUMENT : If cbSrc is an invalid size6713// SYMCRYPT_BUFFER_TOO_SMALL : If cbDst is not large enough6714// (this can always be avoided if cbDst >= cbSrc+15)6715// SYMCRYPT_MEMORY_ALLOCATION_FAILURE : If there is insufficient memory for the operation6716// SYMCRYPT_NO_ERROR : On success6717//6718// Remarks:6719// The standard allows larger plaintexts but there is no requirement to support them, we only support6720// plaintext up to 2^31 bytes because it avoids complexity in handling overflow of 32b buffer sizes, and6721// is larger than practically necessary.6722// The output parameters (pbDst and pcbResult) are only set on success.6723//67246725SYMCRYPT_ERROR6726SYMCRYPT_CALL6727SymCryptAesKwpDecrypt(6728_In_ PCSYMCRYPT_AES_EXPANDED_KEY pExpandedKey,6729_In_reads_(cbSrc) PCBYTE pbSrc,6730SIZE_T cbSrc,6731_Out_writes_to_(cbDst, *pcbResult) PBYTE pbDst,6732SIZE_T cbDst,6733_Out_ SIZE_T* pcbResult );6734//6735// Decrypt a buffer using AES-KWP mode.6736//6737// - pExpandedKey points to the expanded key to use.6738// - pbSrc is the ciphertext source buffer. The source and destination buffers may be6739// identical (in-place decryption) or non-overlapping, but they may not partially overlap.6740// - cbSrc. # bytes of ciphertext. This must be a multiple of 8, >=16, and <=2^31.6741// - pbDst is the plaintext destination buffer. The source and destination buffers may be6742// identical (in-place decryption) or non-overlapping, but they may not partially overlap.6743// - cbDst. # bytes in the destination buffer. This must be large enough to fit the plaintext,6744// a valid plaintext length is in the range [cbSrc-15, cbSrc-8]. If cbDst >= cbSrc-8 then the6745// destination buffer is guaranteed to be large enough.6746// - pcbResult pointer to a variable which receives the length of the plaintext written to pbDst.6747//6748// Returns:6749// SYMCRYPT_INVALID_ARGUMENT : If cbSrc is an invalid size6750// SYMCRYPT_BUFFER_TOO_SMALL : If cbDst is not large enough6751// (this can always be avoided if cbDst >= cbSrc-8)6752// SYMCRYPT_AUTHENTICATION_FAILURE : If pbSrc does not decrypt successfully6753// SYMCRYPT_MEMORY_ALLOCATION_FAILURE : If there is insufficient memory for the operation6754// SYMCRYPT_NO_ERROR : On success6755//6756// Remarks:6757// The standard allows larger plaintexts but there is no requirement to support them, we only support6758// plaintext up to 2^31 bytes because it avoids complexity in handling overflow of 32b buffer sizes, and6759// is larger than practically necessary.6760// The output parameters (pbDst and pcbResult) are only set on success.6761//6762// If we fail to decrypt due to bad data, we return SYMCRYPT_AUTHENTICATION_FAILURE in constant time with6763// respect to how the decrypted data is corrupted. While there is no known attack on AES-KWP abusing6764// differential timing of different failure cases, being constant time for this is cheap, so is a reasonable6765// hardening measure.6766//6767// On success we do not attempt to hide the plaintext length from sidechannels, as this could make it hard6768// for callers with known plaintext length to use precisely sized buffers to decrypt into (i.e. caller6769// knows the valid plaintext is 15 bytes but the API would require caller to provide a 16 byte pbDst). It6770// is expected that in any real use case the length of the plaintext would immediately be used to import the6771// unwrapped key into some other piece of code - so attempting to obscure the plaintext length would not be6772// of any benefit.6773//677467756776////////////////////////////////////////////////////////////////////////////////////////////6777//6778// TLS CBC cipher suites HMAC verification6779//6780// The TLS cipher suites for block cipher modes (typically CBC) are designed in an unfortunate way.6781// The format is:6782// Plaintext | MAC | <padding> | <padding_length>6783// Which is then encrypted by the block cipher.6784// Plaintext is the data being transferred. MAC is the HMAC value over some header data and the plaintext.6785// The padding_length is a byte (range 0-255) that specifies the length of the padding.6786// The padding consists of padding_length bytes (up to 255) Each byte is equal to padding_length.6787// The padding_length is chosen so that length of the whole structure is a multiple of the block cipher block6788// size, so that it can be encrypted with CBC.6789//6790// The problem is that when decrypting this, the natural code will take actions that depend on the padding_length6791// byte before it has been authenticated, and those actions might reveal information about padding_byte. This6792// in turn can be used in an attack that lets the attacker decrypt data.6793// We are particularly concerned with software side channels, where another thread infers information about what the6794// active thread is doing through cache state and other shared CPU state.6795//6796// To address this issue once and for all, we created an implementation of the HMAC verification with the following6797// properties:6798// - It verifies the HMAC in the data structure above.6799// - This is done in a side-channel safe manner, not revealing anything except whether the structure is valid or not.6800// This means that the HMAC computation over the plaintext is constant-time and constant-memory-access pattern6801// irrespective of the padding_length; thus this is a fixed-time implementation for variable-sized inputs.6802// Similarly, the MAC value has to be extracted from a variable location in the input using a fixed memory access6803// pattern.6804//68056806SYMCRYPT_ERROR6807SYMCRYPT_CALL6808SymCryptTlsCbcHmacVerify(6809_In_ PCSYMCRYPT_MAC pMacAlgorithm,6810_In_ PVOID pExpandedKey,6811_Inout_ PVOID pState,6812_In_reads_(cbData) PCBYTE pbData,6813SIZE_T cbData);6814// Verify a TLS CBC cipher suite MAC value6815// - macAlgorithm: one of SymCryptHmacSha1Algorithm, SymCryptHmacSha256Algorithm, or SymCryptHmacSha384Algorithm.6816// Other MAC algorithms are not supported.6817// - pState points to an SYMCRYPT_HMAC_SHAXXX_STATE. It is allowed to process data into the state before this call,6818// but the total # bytes processed must be < 2^16.6819// - pbData points to a buffer containing the concatenation of plaintext, MAC, padding, and padding_length.6820// - cbData is the size of the buffer.6821// Note: callers should pass the entire (plaintext | MAC | padding | padding_length) in a single call to get6822// the full side-channel protection.6823// This function returns success if the HMAC verification is successful.6824// It returns an error if the padding or HMAC verification fails.6825// After the call pState is wiped of any sensitive data, just like the SymCryptHmacXxxResult function.6826// Callers have to check the padding_length byte pbData[cbData-1] to determine the size of the plaintext.6827//6828682968306831/*68326833Yes, despite its name, SymCrypt supports asymmetric cryptographic algorithms.6834The asymmetric implementations have the following primary design goals:6835- Implement asymmetric cryptographic algorithms like RSA, DSA, DH, ECDSA, ECDH, etc.6836- Protect against all software-based side-channel attacks6837- Protect against those hardware-based side-channel attacks that can be practically protected against in software.6838- High performance, dynamically using CPU features that are available on the current CPU stepping.6839- Support small code and small memory environments.6840- Support environments that need to control memory allocations.68416842The primary use-case is for SymCrypt to be the crypto library for MS products. This includes high-performance6843scenarios such as TLS server termination, and low-footprint uses such as Bootmgr.6844SymCrypt supports applications such as firmware updates for embedded CPUs where code and memory6845footprint are of overriding importance.68466847Side channel attacks:6848Defence against side channel attacks play an important part in the design and implementation of6849SymCrypt. Side channel attacks are a class of attacks on cryptographic systems where the attacker6850gets some information about a cryptographic computation in addition to the inputs and outputs.6851For example, any of the following information could be retrieved by the attacker:6852- The time it takes to perform a computation (either exactly or approximately)6853- The power usage over time of the CPU.6854- The noise made by the computer's power supply (a function of the CPU power consumption)6855- Which cache lines are evicted from the attacker's thread A by a computation in thread B.6856These may sound like esoteric attacks, but all of them have been used in practical demonstrations6857to attack cryptographic systems.68586859SymCrypt uses the following API rules to protect against side-channel attacks:6860- Information is divided into two classes: public information and private information.6861- Public information is allowed to leak through side channels, and the library makes no attempt to hide6862public information.6863- Private information is protected against side-channel attacks to the best ability of the library.6864Unless otherwise documented, all information is treated as private.6865Functions may document that a particular value is "published". This means that the function may use6866the value in a way that is not side-channel safe, so any security analysis that considers6867side-channel attacks must assume that the published value is public and known by the attacker.68686869The following information is always assumed to be public, and thus known to any side-channel attacker:6870- Which SymCrypt function is being called.6871- The location of any of the buffers passed as arguments.6872- The size parameter of any buffer passed as an argument.6873- Any details that cause a function to return an error.6874Thus, it is important that callers who wish to be side-channel safe ensure that their buffer locations and sizes6875do not reveal any information, and that they do not make any calls that result in an error, unless there is no6876need for secrecy when an error occurs.68776878Because pointer values are all public (the memory address cannot be hidden on modern CPUs if the buffer is accessed)6879side-channel safe code ends up using masked operations, such as masked-copy where the copy is done or not done6880depending on a mask parameter to the function.6881SymCrypt exposes a set of masked functions that applications can use for their own side-channel safe operations.68826883The following coding rules are used to protect private information:6884- The sequence of instructions executed is independent of private information.6885- The sequence of memory operations (read/write) and memory addresses accessed is independent of private information.6886- Private information is not used in instructions whose timing may depend on the data being processed.6887As far as we know these rules stop all software-based side-channel attacks, and many hardware-based ones.68886889One remaining line of attack is to feed the algorithm with values that are special. For example, an RSA6890decryption may receive a value that contains many zeroes modulo one prime. If the power consumption of the6891multiply instruction reveals whether one of the multiplicands is zero, then the attacker might learn6892useful information. Note that this is a pure hardware attack, it is not applicable to software attackers.6893Protecting against this style of attack is an area that still needs more research. Where applicable we6894document the additional protections that SymCrypt provides.689568966897Running with CHKed code:6898All binaries that use SymCrypt must build CHKed versions of the binary (linking the CHKed version of SymCrypt)6899and perform full test runs on the CHKed version.6900Due to the performance and operational requirements, the production-optimized SymCrypt library API cannot6901check all buffer sizes or even be fully SAL-annotated.6902The necessary size information is simply not available at every call point, and passing6903the size information around would add too much overhead.6904The CHKed version of the library adds additional code & per-object storage to be able to implement check that6905are broadly equivalent to what SAL would normally check.6906SAL checks are part of the SDL requirements and need to be done on all Microsoft products.6907Though this requirement cannot strictly speaking be satisfied with the SymCrypt library, running the CHKed6908version through full validation is the best equivalent, and therefore should be considered mandatory.69096910Please ensure that the validation runs exercise all the border-cases of largest and smallest sizes, as well as6911intermediate sizes for the parameters.69126913*/691469156916//6917// Caller-provided functions6918//6919// Some of the large-integer and asymmetric algorithm functions use callbacks.6920// The callback functions do not have to be functional for binaries that only use the symmetric algorithm6921// implementations.6922// Use of callbacks is documented in each function that uses them.6923//69246925PVOID6926SYMCRYPT_CALL6927SymCryptCallbackAlloc( SIZE_T nBytes );6928//6929// Allocate a buffer of nBytes; returns NULL on failure.6930// Returned pointer must be aligned to a multiple of SYMCRYPT_ASYM_ALIGN_VALUE.6931//69326933VOID6934SYMCRYPT_CALL6935SymCryptCallbackFree( PVOID pMem );6936//6937// Called by SymCrypt to free a buffer previously allocated by SymCryptCallbackAlloc().6938// Note that callers should never call these functions directly. Buffers that were returned6939// from the SymCrypt API are freed with SymCryptFree* functions, not this function.6940//69416942SYMCRYPT_ERROR6943SYMCRYPT_CALL6944SYMCRYPT_WEAK_SYMBOL6945SymCryptCallbackRandom(6946_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,6947SIZE_T cbBuffer );6948//6949// Fill the buffer with uniformly distributed random bytes from a cryptographically strong RNG source.6950//69516952PVOID6953SYMCRYPT_CALL6954SymCryptCallbackAllocateMutexFastInproc(void);6955//6956// Allocate and initialize a mutex object; returns NULL on failure.6957//6958// Fast indicates that users of the mutex will only hold it for a short period of time, so it6959// is not expected that threads should need to sleep before acquiring the mutex. (i.e. can be6960// implemented by a spinlock in kernel mode).6961// Inproc indicates the mutex is only used for synchronization between threads in a single process.6962//6963// Users of the library in contexts where mutexes are not available can set this callback to always6964// return NULL, and attempts to use APIs requiring it will fail at runtime.6965//69666967VOID6968SYMCRYPT_CALL6969SymCryptCallbackFreeMutexFastInproc( _Inout_ PVOID pMutex );6970//6971// Free a mutex object previously created by SymCryptCallbackAllocateMutexFastInproc6972//69736974VOID6975SYMCRYPT_CALL6976SymCryptCallbackAcquireMutexFastInproc( _Inout_ PVOID pMutex );6977//6978// Take exclusive ownership of a mutex object allocated by SymCryptCallbackAllocateMutexFastInproc.6979//6980// This call must also ensure memory ordering such that stores before the previous call to6981// SymCryptCallbackReleaseMutexFastInproc with this mutex are observable by loads after this call.6982//69836984VOID6985SYMCRYPT_CALL6986SymCryptCallbackReleaseMutexFastInproc( _Inout_ PVOID pMutex );6987//6988// Relinquish ownership of a mutex object allocated by SymCryptCallbackAllocateMutexFastInproc and6989// acquired by SymCryptCallbackAcquireMutexFastInproc.6990//69916992//==============================================================================================6993// Object types for high-level API6994//6995// SYMCRYPT_RSAKEY A key that stores the information for the RSA algorithms (encryption and signing).6996// It always contains the RSA parameters / public key, and may or may not contain6997// the associated private key.6998// SYMCRYPT_DLGROUP A discrete log group to be used for the DSA and DH algorithms. It contains the6999// group parameters (P,[Q],G) (The prime Q is optional).7000// SYMCRYPT_DLKEY A "discrete log" key that stores the information for the DSA and DH algorithms. It7001// always contains a public key, and may or may not contain the associated private key.7002// SYMCRYPT_ECURVE An elliptic curve over a prime field. Contains field prime, curve parameters,7003// and distinguished point (generator).7004// SYMCRYPT_ECKEY An elliptic curve key for the ECDH and ECDSA algorithms. It always contains a7005// public key, and may or may not contain the associated private key.7006//7007// See symcrypt_internal.h for structure definitions.7008//70097010//==============================================================================================7011// Supported formats and parameters7012//70137014typedef enum _SYMCRYPT_NUMBER_FORMAT {7015SYMCRYPT_NUMBER_FORMAT_LSB_FIRST = 1,7016SYMCRYPT_NUMBER_FORMAT_MSB_FIRST = 2,7017} SYMCRYPT_NUMBER_FORMAT;7018//7019// SYMCRYPT_NUMBER_FORMAT is used to specify the number format for import and export7020// of BYTE arrays. We support the following two number formats:7021// Let p[0], ..., p[n-1] be an array containing n bytes:7022// LSB_FIRST:7023// Value = \sum_{i=0}^{n-1} p[i] * 2^{8*i}7024// = p[0] + 2^8 * p[1] + 2^{16} * p[2] + ...7025//7026// MSB_FIRST:7027// Value = \sum_{i=0}^{n-1} p[n-1-i] * 2^{8*i}7028// = p[n-1] + 2^8 * p[n-2] + 2^{16} * p[n-3] + ...7029//70307031typedef struct _SYMCRYPT_RSA_PARAMS {7032UINT32 version; // Version of the parameters structure7033UINT32 nBitsOfModulus; // Number of bits in the modulus7034UINT32 nPrimes; // Number of primes, 0 if object is only for public key7035UINT32 nPubExp; // Number of public exponents (typically 1)7036} SYMCRYPT_RSA_PARAMS, *PSYMCRYPT_RSA_PARAMS;7037typedef const SYMCRYPT_RSA_PARAMS * PCSYMCRYPT_RSA_PARAMS;7038//7039// SYMCRYPT_RSA_PARAMS is used to specify all the parameters needed for creation of an7040// RSA key object. The above is version 1 of the parameters.7041// Currently, we only support nPubExp = 1 and nPrimes = 0 or 2.7042// Note: nPrimes > 2 and nPubExp > 1 allow faster and more flexible7043// RSA functionality. Though currently not supported, these parameters make it easy to add7044// support in the future.7045//70467047// Notation for elliptic curve parameters and functions7048// ====================================================70497050// E The elliptic curve group. This is typically represented as the set of 2D points (with7051// coordinates from a finite field) that satisfy a specific curve equation.7052// An example equation is y^2 = x^3 + Ax + B for A,B. The set E also7053// contains a special "zero" point denoted by O.7054// |E| The total number of points on the elliptic curve group E.7055// G A special point in E which generates a (prime) order subgroup.7056// GOrd The (prime) order of the generator point G. Therefore, GOrd * G = O.7057// h The cofactor of the curve. It is defined as h = |E| / GOrd. Typical7058// cofactors are 4 (NUMS curves), and 8 (curve 25519).70597060// Definitions7061// ===========70627063// A "proper public key" (PPK) on the curve E is defined to be an arbitrary nonzero point of the7064// subgroup generated by the point G.70657066// A "proper secret key" (PSK) is the logarithm of a "proper public key" with7067// respect to G. Therefore, if Q is the PPK, then the corresponding PSK is the unique7068// integer s with 0 < s < GOrd such that s*G = Q.70697070// If the cofactor of the curve is equal to 1, then the entire group E is generated by7071// the point G and all nonzero points in E are "proper public keys".70727073// Otherwise, an arbitrary point on the curve might or might not belong to the subgroup7074// generated by G. Furthermore, in this case, an arbitrary point P may have order equal7075// to the cofactor (or smaller), i.e. h*P=O, or an order larger than GOrd.70767077// To securely handle the cases where "non-proper" public keys are imported from possibly malicious7078// sources, the creators of curve parameters impose several restrictions on the secret keys7079// and the algorithms used. For example, the scalar multiplication algorithm for NUMS curves7080// always pre-multiplies a point by the cofactor; in order to zero-out any possible7081// components of lower order ("low-order clearing"). Curve 25519 imposes this by asserting7082// that all secret keys have the 3 lowest bits set to 0, which is equivalent to multiplying7083// by h=8.70847085typedef enum _SYMCRYPT_ECURVE_GEN_ALG_ID {7086SYMCRYPT_ECURVE_GEN_ALG_ID_NULL = 0,7087} SYMCRYPT_ECURVE_GEN_ALG_ID;7088//7089// SYMCRYPT_ECURVE_GEN_ALG_ID is used to specify (if available) the algorithm that7090// generates the curve parameters from the provided seed.7091//709270937094typedef struct _SYMCRYPT_ECURVE_PARAMS_V2_EXTENSION {7095UINT32 PrivateKeyDefaultFormat;7096UINT32 HighBitRestrictionNumOfBits;7097UINT32 HighBitRestrictionPosition;7098UINT32 HighBitRestrictionValue;7099} SYMCRYPT_ECURVE_PARAMS_V2_EXTENSION, *PSYMCRYPT_ECURVE_PARAMS_V2_EXTENSION;7100typedef const SYMCRYPT_ECURVE_PARAMS_V2_EXTENSION * PCSYMCRYPT_ECURVE_PARAMS_V2_EXTENSION;7101//7102// SYMCRYPT_ECURVE_PARAMS_V2_EXTENSION is used to specify restrictions and default formats7103// for known curves. The possible formats and restriction are explained below.7104//71057106// Secret key formats7107// ==================7108// The possible secret key formats in SymCrypt are shown below. For all formats, s denotes7109// a "proper secret key" defined as above. I.e. 0 < s < GOrd.7110//7111// 1. "Canonical": s7112// 2. "DivH": s/h mod GOrd7113// 3. "DivHTimesH": h*(s/h mod GOrd)7114// 4. "TimesH": h*s <-- This format is currently unsupported7115//7116// Remarks:7117// - The above formats apply **only to external formats**: When somebody is7118// importing a secret key (from test vectors, for example) or exporting a key.7119// The internal format of the secret keys might be one of them or something totally7120// different; the internal format is not visible to the caller.7121// - Formats 3 and 4 have bigger storage requirements compared to 1 and 2, as7122// the key can be up to |E|.7123// - When h=1 all formats are identical. This is the case for NIST curves.7124// - The NUMS curves use the "DivH" secret key format in the test vectors and the7125// multiplication algorithm implicitly multiplies by h.7126// - Curve 25519 uses the "DivHTimesH" secret key format in the test vectors.7127typedef enum _SYMCRYPT_ECKEY_PRIVATE_FORMAT {7128SYMCRYPT_ECKEY_PRIVATE_FORMAT_NULL = 0,7129SYMCRYPT_ECKEY_PRIVATE_FORMAT_CANONICAL = 1,7130SYMCRYPT_ECKEY_PRIVATE_FORMAT_DIVH = 2,7131SYMCRYPT_ECKEY_PRIVATE_FORMAT_DIVH_TIMESH = 3,7132} SYMCRYPT_ECKEY_PRIVATE_FORMAT;71337134// High bit restrictions7135// =====================7136// A high bit restriction is a requirement for some of the high bits of the secret keys7137// (usually the most significant bits of the curve).7138// Currently only curve 25519 imposes such a restriction: That the bits 255 and 254 of the7139// secret key in the "DivHTimesH" format are 0 and 1, respectively.7140//7141// The high bit restrictions specification takes the following form:7142// - Number of bits that are specified7143// - Bit position of the lowest bit to be specified (starting from 0 for the LSB)7144// - The bit values7145// The bits that are specified refer to the relevant secret key format.7146// For Canonical and DivH formats the total number of bits is the # bits of GOrd-1.7147// For DivHTimesH and TimesH formats the total number of bits is the # bits of |E|-1.7148//7149// Note: as GOrd must be prime, #bits(Gord) == #bits(Gord-1). The same is true7150// for |E|=h*GOrd as it cannot be a power of 2.7151//7152// The HighBitRestrictionNumOfBits field is a value between 0 and 32 (inclusive)7153// and specifies how many bits of the HighBitRestrictionValue are used (starting7154// from the least significant bit of the value). The bits that are restricted are7155// the bits [HighBitRestrictionPosition+HighBitRestrictionNumOfBits-1, ..., HighBitRestrictionPosition]7156//7157// For example, let's assume it is required that the bits [104, 103, ..., 100]7158// of all private keys of a curve are always 11011.7159// Then the parameters should be set to7160// HighBitRestrictionNumOfBits = 57161// HighBitRestrictionPosition = 1007162// HighBitRestrictionValue = 0x1B7163//716471657166typedef struct _SYMCRYPT_ECURVE_PARAMS {7167UINT32 version; // Version of the parameters structure (see comment below)7168SYMCRYPT_ECURVE_TYPE type; // Type of the curve7169SYMCRYPT_ECURVE_GEN_ALG_ID algId; // Algorithm ID for generation of parameters from seed7170UINT32 cbFieldLength; // Length of the field elements in bytes7171UINT32 cbSubgroupOrder; // Length of the subgroup in bytes7172UINT32 cbCofactor; // Length of the cofactor in bytes7173UINT32 cbSeed; // Length of the seed7174// This struct is followed in memory by:7175//P[cbFieldLength] Prime of the base field7176//A[cbFieldLength] Coefficient A of all three types of curves7177//B[cbFieldLength] Coefficient B of Weierstrass and Montgomery curves and D for Twisted Edwards curves7178//Gx[cbFieldLength] X-coordinate of the distinguished point (assuming SYMCRYPT_ECPOINT_FORMAT_XY)7179//Gy[cbFieldLength] Y-coordinate of the distinguished point (assuming SYMCRYPT_ECPOINT_FORMAT_XY)7180//n[cbSubGroupOrder] Order of the subgroup generated by the distinguished point7181//h[cbCofactor] Cofactor of the distinguished point7182//S[cbSeed] Seed of the curve71837184//ParamsV2Extension[sizeof(SYMCRYPT_ECURVE_PARAMS_V2_EXTENSION)]; // Only on version 2 of the parameters7185} SYMCRYPT_ECURVE_PARAMS, *PSYMCRYPT_ECURVE_PARAMS;7186typedef const SYMCRYPT_ECURVE_PARAMS * PCSYMCRYPT_ECURVE_PARAMS;7187//7188// SYMCRYPT_ECURVE_PARAMS is used to specify all the parameters needed for the curve generation. The above7189// are versions 1 and 2 of the curve parameters.7190//71917192typedef enum _SYMCRYPT_ECPOINT_FORMAT {7193SYMCRYPT_ECPOINT_FORMAT_X = 1, // One value, encoding the X coordinate only of a point7194SYMCRYPT_ECPOINT_FORMAT_XY = 2, // Two equally-sized values, the first one encoding X and the second one encoding Y7195} SYMCRYPT_ECPOINT_FORMAT;7196//7197// SYMCRYPT_ECPOINT_FORMAT is used to support different elliptic curve point formats, including possible point compression.7198//71997200//========================================================================7201//========================================================================7202// Main schema for object creation, deletion, and management.7203//7204// Object management is the same for most object types. For an object type XXX we have7205// the following functions:7206//7207// PSYMCRYPT_XXX7208// SYMCRYPT_CALL7209// SymCryptXxxAllocate( <size parameters> )7210// Allocates an object of type XXX according to the specified size parameters.7211// If the allocation fails, NULL is returned.7212// If the allocation succeeds, an XXX pointer is returned, and the caller is responsible7213// for freeing the result using SymCryptXxxFree().7214// The value of the new object is undefined.7215// All the parameters to this function are published. (Object sizes cannot be private information.)7216//7217// VOID7218// SYMCRYPT_CALL7219// SymCryptXxxFree( _Inout_ PSYMCRYPT_XXX p )7220// Free an XXX object allocated with SymCryptAllocateXxx().7221// Any storage location in the object that might have contained private information is wiped.7222//7223// UINT327224// SYMCRYPT_CALL7225// SymCryptSizeofXxxFromYyy( <size parameters> );7226// Memory size that is sufficient to store an XXX object with size defined by the <size parameters>.7227// The Yyy specifies the form of the size parameters, for example Ecurve.7228// This is a runtime function as the size of an object is a run-time decision dependent on the CPU stepping.7229// The result is always a multiple of the alignment requirements of this object type, so arrays can be built7230// using this element size.7231//7232// SYMCRYPT_SIZEOF_XXX_FROM_YYY( <size parameters> )7233// This is a compile-time macro that computes a value not less than the SymCryptSizeofXxxFromYyy function, and7234// is suitable to statically compute the size of a memory buffer for an object.7235// (Not defined for all types.)7236//7237// PSYMCRYPT_XXX7238// SYMCRYPT_CALL7239// SymCryptXxxCreate(7240// _Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,7241// SIZE_T cbBuffer,7242// <size parameters> );7243// Create an XXX object from the provided (pbBuffer, cbBuffer) space.7244// This function performs the necessary initializations of the object, but does not assign or set a value.7245// The object will be able to store values up to size determined by the <size parameters>.7246// Requirement:7247// - pbBuffer is aligned to SYMCRYPT_ASYM_ALIGN_VALUE. Note that this can be a stricter requirement than7248// SYMCRYPT_ALIGNED, and memory allocation functions might not return pointers that are suitably7249// aligned. For some object types and some CPUs, the alignment requirements might be less strict.7250// The main purpose of this relaxation is to always allow objects that are spaced7251// SymCryptSizeofXxxFromYyy apart. The common usage is to create an array of objects. The array7252// starts at a SYMCRYPT_ASYM_ALIGNed location, with each element SymCryptSizeofXxxFromYyy(..) bytes long.7253// - cbBuffer >= SymCryptSizeofXxxFromYyy( <size parameters> )7254// - (pbBuffer,cbBuffer) memory must be exclusively used by this object.7255// The last requirement ensures that all objects are non-overlapping (except for API functions7256// that explicitly create overlapping objects).7257// All parameters are published.7258// It is always safe to choose7259// cbBuffer = SymCryptSizeofXxxFromYyy( <size parameters> )7260// The returned object pointer is simply a cast of the pbBuffer pointer.7261// Callers that manage arrays of objects can reconstruct the PSYMCRYPT_XXX by casting the buffer pointer7262// to the right type.7263// An object that is created with this function should be wiped, even if it doesn't contain private data.7264// The SymCryptXxxWipe() function also frees any associated data that the library may maintain.7265//7266// VOID7267// SYMCRYPT_CALL7268// SymCryptXxxWipe( _Out_ PSYMCRYPT_XXX Dst )7269// All private information in the Dst object is wiped, and any associated data is freed.7270// Unless otherwise specified, the Dst object is left in an undefined state.7271// An SymCryptXxxAllocate-d object does not have to be wiped before it is freed7272// because the SymCryptXxxFree function will perform the wipe.7273// However, SymCryptXxxCreate-d objects should always be wiped even if they don't contain7274// secret data, as the wipe also frees any associated data the library may maintain.7275//7276// VOID7277// SYMCRYPT_CALL7278// SymCryptXxxCopy(7279// _In_ PCSYMCRYPT_XXX pxSrc,7280// _Out_PSYMCRYPT_XXX pxDst );7281// Dst = Src.7282// Requirement: The <size parameters> of both objects should the same.7283// Src must be in a defined state, it is not valid to copy an undefined object.7284// Src and Dst may be the same object (though that is a no-op).7285//72867287//========================================================================7288// RSAKEY objects' API7289//72907291#define SYMCRYPT_SIZEOF_RSAKEY_FROM_PARAMS( modBits, nPrimes, nPubExps ) \7292SYMCRYPT_INTERNAL_SIZEOF_RSAKEY_FROM_PARAMS( modBits, nPrimes, nPubExps )7293// Return a buffer size large enough to create an RSA key in which the specified7294// modulus size, # primes, # public exponents, and upper bound for the bitsize of each public exponent.7295// If the object will only contain a public key, nPrimes can be set to 072967297PSYMCRYPT_RSAKEY7298SYMCRYPT_CALL7299SymCryptRsakeyAllocate(7300_In_ PCSYMCRYPT_RSA_PARAMS pParams,7301_In_ UINT32 flags );7302//7303// Allocate and create a new RSAKEY object sized according to the parameters.7304// If the SYMCRYPT_RSAKEY object will only be used for a public key, the7305// SYMCRYPT_RSA_PARAMS structure may set nPrimes = 0. Use of7306// SymCryptRsakeySetValueFromPrivateExponent requires nPrimes = 2.7307//7308// This call does not initialize the key. It should be7309// followed by a call to SymCryptRsakeyGenerate or7310// SymCryptRsakeySetValue*.7311//7312// No flags are specified for this function.7313//73147315VOID7316SYMCRYPT_CALL7317SymCryptRsakeyFree( _Out_ PSYMCRYPT_RSAKEY pkObj );73187319UINT327320SYMCRYPT_CALL7321SymCryptSizeofRsakeyFromParams( _In_ PCSYMCRYPT_RSA_PARAMS pParams );7322// If the to-be-allocated SYMCRYPT_RSAKEY object will only be used for a public key, the7323// SYMCRYPT_RSA_PARAMS structure may set nPrimes = 0.73247325PSYMCRYPT_RSAKEY7326SYMCRYPT_CALL7327SymCryptRsakeyCreate(7328_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,7329SIZE_T cbBuffer,7330_In_ PCSYMCRYPT_RSA_PARAMS pParams );7331//7332// Create an RSAKEY object from a buffer, but does not initialize it.7333// If the SYMCRYPT_RSAKEY object will only be used for a public key, the7334// SYMCRYPT_RSA_PARAMS structure may set nPrimes = 0. Use of7335// SymCryptRsakeySetValueFromPrivateExponent requires nPrimes = 2.7336//7337// This call does not initialize the key. It should be7338// followed by a call to SymCryptRsakeyGenerate or7339// SymCryptRsakeySetValue*.7340//73417342VOID7343SYMCRYPT_CALL7344SymCryptRsakeyWipe( _Out_ PSYMCRYPT_RSAKEY pkDst );73457346//7347//VOID7348//SYMCRYPT_CALL7349//SymCryptRsakeyCopy(7350// _In_ PCSYMCRYPT_RSAKEY pkSrc,7351// _Out_ PSYMCRYPT_RSAKEY pkDst );7352//7353// This function is currently not available.7354//73557356//========================================================================7357// DLGROUP objects' API7358//73597360PSYMCRYPT_DLGROUP7361SYMCRYPT_CALL7362SymCryptDlgroupAllocate( UINT32 nBitsOfP, UINT32 nBitsOfQ );7363//7364// Allocate a Discrete Logarithm group object suitable for the given sizes.7365//7366// nBitsOfP: Maximum number of bits of the field prime P. Specifying a value larger7367// than the actual size is allowed, but inefficient.7368// nBitsOfQ: Maximum number of bits of the group order Q. Specify the size of Q,7369// or 0 if the size of Q is not (yet) known.7370//7371// This call does not initialize the DLGROUP. It should be followed7372// by a call to SymCryptDlgroupGenerate or SymCryptDlgroupSetValue.7373//7374// nBitsOfQ is allowed to be equal to 0 and signifies that the size of Q7375// is unknown or Q does not exist. This may be used when creating a DLGROUP7376// for the DH algorithm which does not use a prime Q.7377//7378// Setting nBitsOfQ to something bigger than 0 signifies that the size of7379// the prime Q is known and if a future caller tries to import a bigger Q then7380// the SymCryptDlgroupSetValue call will fail.7381//7382// Technically nBitsOfQ should always be strictly less than nBitsOfP, as Q divides7383// P-1. For simplicity, it is allowed that callers specify nBitsOfQ equal to nBitsOfP7384// in this call, but SymCrypt will treat this as setting nBitsOfQ to (nBitsOfP-1).7385//7386// Setting nBitsOfQ to 0 might result in a bigger size of the DLGROUP object7387// compared to setting it to a specific size (see SymCryptSizeofDlgroupFromBitsizes).7388//7389// Requirements:7390// - nBitsOfP >= nBitsOfQ7391//73927393VOID7394SYMCRYPT_CALL7395SymCryptDlgroupFree( _Out_ PSYMCRYPT_DLGROUP pgObj );73967397UINT327398SYMCRYPT_CALL7399SymCryptSizeofDlgroupFromBitsizes( UINT32 nBitsOfP, UINT32 nBitsOfQ );7400//7401// This call returns the memory size that is sufficient to store a7402// DLGROUP object with primes P,Q of size nBitsOfP and nBitsOfQ,7403// respectively (L,N parameters in FIPS 186-3 specs).7404//7405// Requirements:7406// - nBitsOfP >= nBitsOfQ7407//7408// Remarks:7409// - The value in nBitsOfQ is allowed to be equal to 07410// (see SymCryptDlgroupAllocate).7411//7412// - When nBitsOfQ!=0 this is a monotonic function w.r.t. a partial order on N^2.7413// I.e. for all fixed (nBitsOfP_0,nBitsOfQ_0) and (nBitsOfP_1,nBitsOfQ_1) with7414// nBitsOfQ_0>0 and nBitsOfQ_1>0,7415//7416// (nBitsOfP_0<=nBitsOfP_1 AND nBitsOfQ_0<=nBitsOfQ_1) implies that7417// F(nBitsOfP_0,nBitsOfQ_0) <= F(nBitsOfP_1,nBitsOfQ_1)7418// where F is the function SymCryptSizeofDlgroupFromBitsizes.7419//7420// - F(nBitsOfP, 0)=F(nBitsOfP, nBitsOfP-1). Thus when nBitsOfQ==0 the7421// function takes the maximum value for a fixed nBitsOfP.7422//74237424PSYMCRYPT_DLGROUP7425SYMCRYPT_CALL7426SymCryptDlgroupCreate(7427_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,7428SIZE_T cbBuffer,7429UINT32 nBitsOfP,7430UINT32 nBitsOfQ );7431//7432// Creates a DL group object, but does not initialize it. It must be followed7433// by a call to SymCryptDlgroupGenerate or SymCryptDlgroupSetValue.7434//7435// - pbBuffer,cbBuffer: memory buffer to create the object out of. The required size7436// can be computed with SymCryptSizeofDlgroupFromBitsizes().7437// - nBitsOfP: number of bits of the field prime P.7438// - nBitsOfQ: number of bits of the group order Q, or 0 if the size of Q is not (yet) known.7439//74407441VOID7442SYMCRYPT_CALL7443SymCryptDlgroupWipe( _Out_ PSYMCRYPT_DLGROUP pgDst );74447445VOID7446SYMCRYPT_CALL7447SymCryptDlgroupCopy(7448_In_ PCSYMCRYPT_DLGROUP pgSrc,7449_Out_ PSYMCRYPT_DLGROUP pgDst );74507451//========================================================================7452// DLKEY objects' API7453//74547455PSYMCRYPT_DLKEY7456SYMCRYPT_CALL7457SymCryptDlkeyAllocate( _In_ PCSYMCRYPT_DLGROUP pDlgroup );7458//7459// This call does not initialize the key. It should be7460// followed by a call to SymCryptDlkeyGenerate or7461// SymCryptDlkeySetValue.7462//74637464VOID7465SYMCRYPT_CALL7466SymCryptDlkeyFree( _Out_ PSYMCRYPT_DLKEY pkObj );74677468UINT327469SYMCRYPT_CALL7470SymCryptSizeofDlkeyFromDlgroup( _In_ PCSYMCRYPT_DLGROUP pDlgroup );74717472PSYMCRYPT_DLKEY7473SYMCRYPT_CALL7474SymCryptDlkeyCreate(7475_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,7476SIZE_T cbBuffer,7477_In_ PCSYMCRYPT_DLGROUP pDlgroup );74787479VOID7480SYMCRYPT_CALL7481SymCryptDlkeyWipe( _Out_ PSYMCRYPT_DLKEY pkDst );74827483VOID7484SYMCRYPT_CALL7485SymCryptDlkeyCopy(7486_In_ PCSYMCRYPT_DLKEY pkSrc,7487_Out_ PSYMCRYPT_DLKEY pkDst );74887489//========================================================================7490// ECURVE objects' API is slightly different than the above API schema because of the close7491// relation to multiple parameters, the fact that they contain public information,7492// and that they are persisted by the callers.7493// Thus, the Allocate function takes in all the curve parameters and there are no Create,7494// Wipe, or Copy functions.7495//74967497PSYMCRYPT_ECURVE7498SYMCRYPT_CALL7499SymCryptEcurveAllocate(7500_In_ PCSYMCRYPT_ECURVE_PARAMS pParams,7501_In_ UINT32 flags );7502//7503// Allocate memory and create an ECURVE object which is defined7504// by the parameters in pParams.7505//7506// - pParams: parameters that define the curve7507// - flags: Not used, must be zero.7508//7509// Future versions might use the flags to enable different features/tradeoffs.7510// There are a number of interesting memory/speed/pre-computation cost trades that can be made.7511// For example, pre-computing multiples of the distinguished point, or (parallel?) pre-computation7512// of (r, rG) pairs for random r values.7513//7514// This function applies limited validation of the pParams. The validation is intended to eliminate7515// the threat of denial-of-service when hostile parameters are presented. It does not ensure that7516// the parameters make sense, define a proper curve, or that any elliptic-curve operations made on7517// the curve built from these parameters will fail, succeed or provide any security.7518// The only guarantee provided for invalid parameters is that all operations on this curve will7519// not crash and will return in some reasonable amount of time.7520//7521// Returns NULL if out of memory or the parameters are deemed invalid.7522// If the return value is not NULL, the object must later be freed with SymCryptEcurveFree().7523//75247525VOID7526SYMCRYPT_CALL7527SymCryptEcurveFree( _Out_ PSYMCRYPT_ECURVE pCurve );75287529//========================================================================7530// ECKEY objects' API is slightly different than the above API schema in the sense that they7531// take as input an ECURVE object pointer instead of the number of digits.7532//75337534PSYMCRYPT_ECKEY7535SYMCRYPT_CALL7536SymCryptEckeyAllocate( _In_ PCSYMCRYPT_ECURVE pCurve );75377538VOID7539SYMCRYPT_CALL7540SymCryptEckeyFree( _Out_ PSYMCRYPT_ECKEY pkObj );75417542UINT327543SYMCRYPT_CALL7544SymCryptSizeofEckeyFromCurve( _In_ PCSYMCRYPT_ECURVE pCurve );75457546PSYMCRYPT_ECKEY7547SYMCRYPT_CALL7548SymCryptEckeyCreate(7549_Out_writes_bytes_( cbBuffer ) PBYTE pbBuffer,7550SIZE_T cbBuffer,7551PCSYMCRYPT_ECURVE pCurve );75527553VOID7554SYMCRYPT_CALL7555SymCryptEckeyWipe( _Out_ PSYMCRYPT_ECKEY pkDst );75567557VOID7558SymCryptEckeyCopy(7559_In_ PCSYMCRYPT_ECKEY pkSrc,7560_Out_ PSYMCRYPT_ECKEY pkDst );756175627563//=====================================================7564// Flags for asymmetric key generation and import75657566// These flags are introduced primarily for FIPS purposes. For FIPS 140-3 rather than expose to the7567// caller the specifics of what tests will be run with various algorithms, we are sanitizing flags7568// provided on asymmetric key generation and import to enable the caller to indicate their intent,7569// and for SymCrypt to perform the required testing.7570// Below we define the flags that can be passed and when a caller should set them.7571// The specifics of what tests will be run are likely to change over time, as FIPS requirements and7572// our understanding of how best to implement them, change over time. Callers should not rely on7573// specific behavior.757475757576// Validation required by FIPS is enabled by default. This flag enables a caller to opt out of this7577// validation.7578#define SYMCRYPT_FLAG_KEY_NO_FIPS (0x100)75797580// When opting out of FIPS, SymCrypt may still perform some sanity checks on key import7581// In very performance sensitive situations where a caller strongly trusts the values it is passing7582// to SymCrypt and does not care about FIPS (or can statically prove properties about the imported7583// keys), a caller may specify SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION in addition to7584// SYMCRYPT_FLAG_KEY_NO_FIPS to skip costly checks7585#define SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION (0x200)75867587// Callers must specify what algorithm(s) a given asymmetric key will be used for.7588// This information will be tracked by SymCrypt, and attempting to use the key in an algorithm it7589// was not generated or imported for will result in failure.7590// If no algorithm is specified then the key generation or import function will fail.7591#define SYMCRYPT_FLAG_DLKEY_DSA (0x1000)7592#define SYMCRYPT_FLAG_DLKEY_DH (0x2000)75937594#define SYMCRYPT_FLAG_ECKEY_ECDSA (0x1000)7595#define SYMCRYPT_FLAG_ECKEY_ECDH (0x2000)75967597#define SYMCRYPT_FLAG_RSAKEY_SIGN (0x1000)7598#define SYMCRYPT_FLAG_RSAKEY_ENCRYPT (0x2000)75997600//=====================================================7601// RSA key operations76027603BOOLEAN7604SYMCRYPT_CALL7605SymCryptRsakeyHasPrivateKey( _In_ PCSYMCRYPT_RSAKEY pkRsakey );7606//7607// Returns TRUE if the pkRsakey object has private key information.7608//76097610UINT327611SYMCRYPT_CALL7612SymCryptRsakeySizeofModulus( _In_ PCSYMCRYPT_RSAKEY pkRsakey );7613//7614// Returns the (tight) size in bytes of a byte array big enough to store7615// the modulus of the key.7616//76177618UINT327619SYMCRYPT_CALL7620SymCryptRsakeyModulusBits( _In_ PCSYMCRYPT_RSAKEY pkRsakey );7621//7622// Return the number of bits in the RSA modulus7623//76247625UINT327626SYMCRYPT_CALL7627SymCryptRsakeySizeofPublicExponent(7628_In_ PCSYMCRYPT_RSAKEY pRsakey,7629UINT32 index );7630//7631// Returns the (tight) size in bytes of a byte array big enough to store7632// the public exponent. The index specifies the index7633// of the public exponent, starting with 0.7634//7635// Remarks:7636// - Currently, only one public exponent is supported, i.e. the only7637// valid index is 0.7638//76397640UINT327641SYMCRYPT_CALL7642SymCryptRsakeySizeofPrime(7643_In_ PCSYMCRYPT_RSAKEY pkRsakey,7644UINT32 index );7645//7646// Returns the (tight) size in bytes of a byte array big enough to store7647// the selected prime of the key. The index specifies the index of the7648// prime, starting at 0.7649//7650// Remarks:7651// - Currently, only two prime RSA is supported, i.e. the only7652// valid indexes are 0 and 1.7653//76547655UINT327656SYMCRYPT_CALL7657SymCryptRsakeyGetNumberOfPublicExponents( _In_ PCSYMCRYPT_RSAKEY pkRsakey );7658//7659// Returns the number of public exponents stored in the key.7660//76617662UINT327663SYMCRYPT_CALL7664SymCryptRsakeyGetNumberOfPrimes( _In_ PCSYMCRYPT_RSAKEY pkRsakey );7665//7666// Returns the number of primes stored in the key.7667//76687669SYMCRYPT_ERROR7670SYMCRYPT_CALL7671SymCryptRsakeyGenerate(7672_Inout_ PSYMCRYPT_RSAKEY pkRsakey,7673_In_reads_opt_( nPubExp ) PCUINT64 pu64PubExp,7674UINT32 nPubExp,7675_In_ UINT32 flags );7676//7677// Generate a new random RSA key using the information from the7678// parameters passed to SymCryptRsaKeyAllocate/SymCryptRsaKeyCreate.7679// PubExp is the array of nPubExp public exponent values, specifying7680// the public exponents for the key.7681// nPubExp must match the # public exponents in the parameters.7682// If pu64PubExp == NULL, nPubExp == 0, and the key requires only one7683// public exponent, then the default exponent 2^16 + 1 is used.7684//7685// Allowed flags:7686//7687// - SYMCRYPT_FLAG_KEY_NO_FIPS7688// Opt-out of performing validation required for FIPS7689//7690// - At least one of the flags indicating what the Rsakey is to be used for must be specified:7691// SYMCRYPT_FLAG_RSAKEY_SIGN7692// SYMCRYPT_FLAG_RSAKEY_ENCRYPT76937694// Described in more detail in the "Flags for asymmetric key generation and import" section above7695//76967697SYMCRYPT_ERROR7698SYMCRYPT_CALL7699SymCryptRsakeySetValue(7700_In_reads_bytes_( cbModulus ) PCBYTE pbModulus,7701SIZE_T cbModulus,7702_In_reads_( nPubExp ) PCUINT64 pu64PubExp,7703UINT32 nPubExp,7704_In_reads_opt_( nPrimes ) PCBYTE * ppPrimes,7705_In_reads_opt_( nPrimes ) SIZE_T * pcbPrimes,7706UINT32 nPrimes,7707SYMCRYPT_NUMBER_FORMAT numFormat,7708UINT32 flags,7709_Inout_ PSYMCRYPT_RSAKEY pkRsakey );7710//7711// Import key material to an RSAKEY object. The arguments are the following:7712// - pbModulus is a pointer to a byte buffer of cbModulus bytes. It cannot be NULL.7713// - pu64PubExp is a pointer to an array of nPubExp UINT64 exponent values.7714// nPubExp must match the RSA parameters used to create the key object.7715// - ppPrimes is an array of nPrimes pointers that point to byte buffers storing7716// the primes. pcbPrimes is an array of nPrimes sizes such that7717// the size of ppPrimes[i] is equal to pcbPrimes[i] for each i in [0, nPrimes-1].7718// - numFormat specifies the number format for all inputs7719//7720// Allowed flags:7721//7722// - SYMCRYPT_FLAG_KEY_NO_FIPS7723// Opt-out of performing validation required for FIPS7724//7725// - SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION7726// Opt-out of performing almost all validation - must be specified with SYMCRYPT_FLAG_KEY_NO_FIPS7727//7728// - At least one of the flags indicating what the Rsakey is to be used for must be specified:7729// SYMCRYPT_FLAG_RSAKEY_SIGN7730// SYMCRYPT_FLAG_RSAKEY_ENCRYPT7731//7732// Described in more detail in the "Flags for asymmetric key generation and import" section above7733//7734// Remarks:7735// - Modulus and all primes are stored in the same format specified by numFormat.7736// - ppPrimes, pcbPrimes, and nPrimes can be NULL, NULL, and 0 respectively, when7737// importing a public key.7738// - Currently, the only acceptable value of nPubExps is 1.7739// - Currently, the only acceptable value of nPrimes is 2 or 0.7740// - Elements of ppPrimes must represent prime numbers.7741// We allow separate sizes for each prime. This seems redundant because all primes7742// are approximately the same size. However, some storage/encoding formats, such as ASN.1,7743// strip leading zeroes, or add an additional leading zero depending on the situation.7744// Allowing separate sizes avoids the need for the caller to make a copy of the data7745// into a possibly slightly larger buffer.7746//77477748SYMCRYPT_ERROR7749SYMCRYPT_CALL7750SymCryptRsakeySetValueFromPrivateExponent(7751_In_reads_bytes_( cbModulus ) PCBYTE pbModulus,7752SIZE_T cbModulus,7753UINT64 u64PubExp,7754_In_reads_bytes_( cbPrivateExponent ) PCBYTE pbPrivateExponent,7755SIZE_T cbPrivateExponent,7756SYMCRYPT_NUMBER_FORMAT numFormat,7757UINT32 flags,7758_Inout_ PSYMCRYPT_RSAKEY pkRsakey );7759//7760// Import private key to an RSAKEY object using a private exponent. This is not generally7761// recommended - where possible it is more efficient to import a private key using primes7762// with SymCryptRsakeySetValue.7763//7764// The arguments are the following:7765// - pbModulus is a pointer to a byte buffer of cbModulus bytes. It cannot be NULL.7766// - u64PubExp is a UINT64 public exponent value.7767// - pbPrivateExponent is a pointer to a byte buffer of cbPrivateExponent bytes. It7768// cannot be NULL.7769// - numFormat specifies the number format for all inputs7770//7771// Allowed flags:7772//7773// - SYMCRYPT_FLAG_KEY_NO_FIPS7774// Opt-out of performing validation required for FIPS7775//7776// - SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION7777// Opt-out of performing almost all validation - must be specified with SYMCRYPT_FLAG_KEY_NO_FIPS7778//7779// - At least one of the flags indicating what the Rsakey is to be used for must be specified:7780// SYMCRYPT_FLAG_RSAKEY_SIGN7781// SYMCRYPT_FLAG_RSAKEY_ENCRYPT7782//7783// Described in more detail in the "Flags for asymmetric key generation and import" section above7784//7785// Remarks:7786//7787// Modulus and Private exponent are stored in the same format specified by numFormat.7788//7789// Internally this attempts to recover a pair of primes (p1, p2) that factorize Modulus.7790// This procedure has following assumptions:7791// Modulus (n) is the product of two prime factors, p1 and p27792// e*d == 1 modulo LCM(p1-1, p2-1)7793// e*d != 1 modulo 2^647794// If any of these assumptions are not met, then the method may fail.7795//77967797SYMCRYPT_ERROR7798SYMCRYPT_CALL7799SymCryptRsakeyGetValue(7800_In_ PCSYMCRYPT_RSAKEY pkRsakey,7801_Out_writes_bytes_( cbModulus ) PBYTE pbModulus,7802SIZE_T cbModulus,7803_Out_writes_opt_( nPubExp ) PUINT64 pu64PubExp,7804UINT32 nPubExp,7805_Out_writes_opt_( nPrimes ) PBYTE * ppPrimes,7806_In_reads_opt_( nPrimes ) SIZE_T * pcbPrimes,7807UINT32 nPrimes,7808SYMCRYPT_NUMBER_FORMAT numFormat,7809UINT32 flags );7810//7811// Export key material from an RSAKEY object. The arguments are the following:7812// - pbModulus is a pointer to a byte buffer of cbModulus bytes.7813// - pu64PubExp is an pointer to an array of nPubExp elements that receives the public exponent values.7814// nPubExp must match the # public exponents in pkRsaKey.7815// - ppPrimes is an array of nPrimes pointers that point to byte buffers storing7816// the primes. pcbPrimes is an array of nPrimes sizes such that7817// the size of ppPrimes[i] is equal to pcbPrimes[i] for each i in [0, nPrimes-1].7818// Remarks:7819// - All parameters are stored in the same format specified by numFormat.7820// - ppPrimes, pcbPrimes, and nPrimes can be NULL, NULL, and 0 respectively, when7821// exporting a public key.7822// - Currently, the only acceptable value of nPubExp is 1 or 0.7823// - Currently, the only acceptable value of nPrimes is 2 or 0.7824// We use separate sizes for each prime. This supports the tight encoding7825// used by CNG export blobs, and uses the same format as RsakeySetValue7826//78277828SYMCRYPT_ERROR7829SYMCRYPT_CALL7830SymCryptRsakeyGetCrtValue(7831_In_ PCSYMCRYPT_RSAKEY pkRsakey,7832_Out_writes_opt_(nCrtExponents) PBYTE * ppCrtExponents,7833_In_reads_(nCrtExponents) SIZE_T * pcbCrtExponents,7834UINT32 nCrtExponents,7835_Out_writes_bytes_opt_(cbCrtCoefficient) PBYTE pbCrtCoefficient,7836SIZE_T cbCrtCoefficient,7837_Out_writes_bytes_opt_(cbPrivateExponent) PBYTE pbPrivateExponent,7838SIZE_T cbPrivateExponent,7839SYMCRYPT_NUMBER_FORMAT numFormat,7840UINT32 flags);7841//7842// Export Crt key material from an RSAKEY object. The arguments are the following:7843// ppCrtExponents is an array of nCrtExponent pointers that point to byte buffers7844// storing the Crt exponents. That is, d mod p-1, d mod q-1.7845// pcbCrtExponents is an array of nCrtExponent sizes such that7846// the size of ppCrtExponents[i] is equal to pcbCrtExponents[i] for each i in [0, nCrtExponent-1]7847// pbCrtCoefficient is a pointer to a byte buffer of cbCrtCoefficient bytes, that is q^{-1} mod p7848// pbPrivateExponent is a pointer to a byte buffer of cbPrivateExponent bytes, that is, d.78497850// Remarks:7851// - All parameters are stored in the same format specified by numFormat.7852// - ppCrtExponents, pcbCrtExponents, and nCrtExponent can be NULL, NULL, and 0 respectively7853// - Currently, the only acceptable value of nCrtExponent is 2 or 0.7854// pbCrtCoefficient, pbPrivateExponent can be NULL;78557856SYMCRYPT_ERROR7857SYMCRYPT_CALL7858SymCryptRsakeyExtendKeyUsage(7859_Inout_ PSYMCRYPT_RSAKEY pkRsakey,7860UINT32 flags );7861//7862// Enable an existing key which has been generated or imported to be used in specified algorithms.7863// Some callers may not know at key generation or import time what algorithms a key will be used for7864// and this API allows the key to be extended for use in additional algorithms. Use of this API may7865// not be compliant with FIPS 140-37866//7867// - flags must be some bitwise OR of the following flags:7868// SYMCRYPT_FLAG_RSAKEY_SIGN7869// SYMCRYPT_FLAG_RSAKEY_ENCRYPT78707871#define SYMCRYPT_DLGROUP_FIPS_LATEST (SYMCRYPT_DLGROUP_FIPS_186_3)78727873SYMCRYPT_ERROR7874SYMCRYPT_CALL7875SymCryptDlgroupGenerate(7876_In_ PCSYMCRYPT_HASH hashAlgorithm,7877_In_ SYMCRYPT_DLGROUP_FIPS fipsStandard,7878_Inout_ PSYMCRYPT_DLGROUP pDlgroup );7879//7880// Generate a Discrete Logarithm Group for use in Diffie-Hellman and DSA.7881//7882// - hashAlgorithm: Hash algorithm to be used for generating the group (if required by the algorithm)7883// - fipsStandard: Which FIPS standard algorithm to use for generating the group.7884// - pDlgroup: group object that will be initialized with a newly generated group.7885//7886// pDlGroup must have been created with SymCryptDlgroupAllocate() or SymCryptDlgroupCreate().7887//7888// If nBitsOfQ was equal to 0 when the DLGROUP was Allocate-d/Create-d7889// (and only in this case), then this function picks a default size7890// for the prime Q according to the following table:7891// - If nBitsOfP <= 160 then the function fails with SYMCRYPT_FIPS_FAILURE7892// - If 160 < nBitsOfP <= 1024 then nBitsOfQ = 1607893// - If 1024 < nBitsOfP <= 2048 then nBitsOfQ = 2567894// - If 2048 < nBitsOfP then nBitsOfQ = 2567895//7896// If fipsStandard == SYMCRYPT_DLGROUP_FIPS_NONE then no FIPS compliance is requested.7897// The code defaults to SYMCRYPT_DLGROUP_FIPS_LATEST.7898//7899// The requirements below address the parameter values after the defaults have been substituted7900// for nBitsOfQ and fipsStandard.7901//7902// Requirements:7903// - pDlgroup!=NULL. Otherwise it returns SYMCRYPT_INVALID_ARGUMENT.7904//7905// - If fipsStandard == SYMCRYPT_DLGROUP_FIPS_186_2, hashAlgorithm MUST be equal to7906// NULL, and nBitsOfQ <= 160 or nBitsOfQ = 0 && nBitsOfP <= 1024.7907//7908// - If fipsStandard == SYMCRYPT_DLGROUP_FIPS_186_3, then hashAlgorithm MUST NOT be equal7909// to NULL.7910//7911// - If nBitsOfHash is the number of bits of the output block of hashAlgorithm,7912// it is required that:7913// nBitsOfQ <= nBitsOfHash <= nBitsOfP7914// (where nBitsOfQ>0 was either provided by the caller of Allocate/Create7915// or it was picked from the above table).7916//7917// - For FIPS 186-2, we have that nBitsOfHash == 160 (SHA1 output size). Therefore7918// this flag can only work with nBitsOfQ up to 160 bits. Anything else will7919// return SYMCRYPT_INVALID_ARGUMENT.7920//79217922SYMCRYPT_ERROR7923SYMCRYPT_CALL7924SymCryptDlgroupSetValueSafePrime(7925SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE dhSafePrimeType,7926_Inout_ PSYMCRYPT_DLGROUP pDlgroup );7927//7928// Sets a Discrete Logarithm Group for use in Diffie-Hellman using a named safe-prime group.7929//7930// - dhSafePrimeType: The type of named safe-prime group to use7931//7932// pDlGroup must have been created with SymCryptDlgroupAllocate() or SymCryptDlgroupCreate().7933//7934// Selects the largest named safe-prime group that will fit in the allocated Dlgroup (based on the7935// values of nBitsOfP and nBitsOfQ used in allocation). It is recommended that callers set nBitsOfQ7936// to 0 in allocation (equivalent to nBitsOfQ = (nBitsOfP-1)) when creating a safe-prime group.7937//7938// Requirements:7939// - pDlgroup was allocated with sufficient bits for the selected P (and Q) to fit. If there is no7940// named safe-prime group with bit size <= the allocated size, it returns SYMCRYPT_INVALID_ARGUMENT.7941// The minimum currently supported bitsize of named safe-prime groups is nBitsOfP = 2048.7942//7943// - dhSafePrimeType!=SYMCRYPT_DLGROUP_DH_SAFEPRIMETYPE_NONE. Otherwise it returns SYMCRYPT_INVALID_ARGUMENT.7944//79457946BOOLEAN7947SYMCRYPT_CALL7948SymCryptDlgroupIsSame(7949_In_ PCSYMCRYPT_DLGROUP pDlgroup1,7950_In_ PCSYMCRYPT_DLGROUP pDlgroup2 );7951//7952// Returns true if pDlgroup1 and pDlgroup2 have same set of P and G, false otherwise.7953//79547955VOID7956SYMCRYPT_CALL7957SymCryptDlgroupGetSizes(7958_In_ PCSYMCRYPT_DLGROUP pDlgroup,7959_Out_ SIZE_T* pcbPrimeP,7960_Out_ SIZE_T* pcbPrimeQ,7961_Out_ SIZE_T* pcbGenG,7962_Out_ SIZE_T* pcbSeed );7963//7964// It returns the tight byte-sizes of each parameter of the group: prime P,7965// prime Q, generator G, and the FIPS domain_parameter_seed.7966//7967// If one of the pointers is NULL then the corresponding size is ignored.7968//7969// Remarks:7970// - If the group has no prime Q, then the returned sizes in *pcbPrimeQ and7971// *pcbSeed will be 0.7972//79737974SYMCRYPT_ERROR7975SYMCRYPT_CALL7976SymCryptDlgroupSetValue(7977_In_reads_bytes_( cbPrimeP ) PCBYTE pbPrimeP,7978SIZE_T cbPrimeP,7979_In_reads_bytes_( cbPrimeQ ) PCBYTE pbPrimeQ,7980SIZE_T cbPrimeQ,7981_In_reads_bytes_( cbGenG ) PCBYTE pbGenG,7982SIZE_T cbGenG,7983SYMCRYPT_NUMBER_FORMAT numFormat,7984_In_opt_ PCSYMCRYPT_HASH pHashAlgorithm,7985_In_reads_bytes_( cbSeed ) PCBYTE pbSeed,7986SIZE_T cbSeed,7987UINT32 genCounter,7988SYMCRYPT_DLGROUP_FIPS fipsStandard,7989_Inout_ PSYMCRYPT_DLGROUP pDlgroup );7990//7991// Import key material to a DLGROUP object.7992// - Prime P is NOT optional and should always be imported.7993// - Prime Q is an optional parameter that may or may not be imported. If not7994// the group will not have a prime Q.7995// - Generator G is an optional parameter. However, if not present, the7996// algorithm will generate a random G of order Q. If both Q and G are missing7997// the calls fails with SYMCRYPT_INVALID_ARGUMENT.7998// - The parameters pHashAlgorithm, pbSeed, cbSeed and genCounter are the generation7999// parameters of the FIPS standards. If fipsStandard is not equal to8000// SYMCRYPT_DLGROUP_FIPS_NONE, the algorithm verifies that the input P,Q,G parameters are properly8001// generated by the corresponding standard.8002// If there is any discrepancy the function returns SYMCRYPT_AUTHENTICATION_FAILURE.8003// Notice that these parameters are imported even if they aren't verified.8004//8005// Requirements:8006// - The number stored in pbPrimeP and pbGenG must have at most nBitsOfP significant bits.8007// Otherwise the function returns SYMCRYPT_INVALID_ARGUMENT.8008// - The number stored in pbPrimeQ must have at most nBitsOfQ where nBitsOfQ is either8009// the **non-zero** value input in the call of Allocate/Create or equal to nBitsOfP if8010// 0 was input.8011// Otherwise the function returns SYMCRYPT_INVALID_ARGUMENT.8012// - The size of the seed cbSeed must be **exactly** equal to the byte-size of the imported8013// modulus Q. Otherwise the function returns SYMCRYPT_INVALID_ARGUMENT.8014//8015// Remarks:8016// - The buffers pbPrimeP, pbPrimeQ, pbGenG must all have the same number8017// format defined by numFormat.8018// - Primes P and (when provided) Q must represent prime numbers.8019//80208021SYMCRYPT_ERROR8022SYMCRYPT_CALL8023SymCryptDlgroupGetValue(8024_In_ PCSYMCRYPT_DLGROUP pDlgroup,8025_Out_writes_bytes_( cbPrimeP ) PBYTE pbPrimeP,8026SIZE_T cbPrimeP,8027_Out_writes_bytes_( cbPrimeQ ) PBYTE pbPrimeQ,8028SIZE_T cbPrimeQ,8029_Out_writes_bytes_( cbGenG ) PBYTE pbGenG,8030SIZE_T cbGenG,8031SYMCRYPT_NUMBER_FORMAT numFormat,8032_Out_ PCSYMCRYPT_HASH * ppHashAlgorithm,8033_Out_writes_bytes_( cbSeed ) PBYTE pbSeed,8034SIZE_T cbSeed,8035_Out_ PUINT32 pGenCounter );80368037//8038// Retrieve the group parameters from a DLGROUP. The buffers should be8039// allocated by the caller. If a pbXXX parameter is NULL (and the cbXXX==0)8040// then this parameter is not returned.8041//8042// Requirements:8043// - All the buffers must have size at least equal to the corresponding8044// size returned by SymCryptDlgroupGetSizes. For the pbSeed buffer the8045// size must be **exactly** equal to the size returned from SymCryptDlgroupGetSizes.8046//8047// Remarks:8048// - If the caller requests a Q but the group does not have one, this function8049// will fail with SYMCRYPT_INVALID_BLOB.8050// - The return value of *ppHashAlgorithm can be NULL if the group was generated8051// by FIPS 186-2.8052//80538054//=====================================================8055// DL flags8056//8057// Also see Generic key validation flags above80588059// SYMCRYPT_FLAG_DLKEY_GEN_MODP:8060// When set on SymCryptDlkeyGenerate call, generate a private key between 1 and P-2.8061// When Q is known, this overrides the default behavior of generating a private key between 1 and Q-1,8062// or 1 and min(2^nBitsPriv-1, Q-1) for named safe-prime groups8063// When Q is not known, this does not affect the behavior8064#define SYMCRYPT_FLAG_DLKEY_GEN_MODP (0x01)80658066//=====================================================8067// DL key operations80688069SYMCRYPT_ERROR8070SYMCRYPT_CALL8071SymCryptDlkeySetPrivateKeyLength( _Inout_ PSYMCRYPT_DLKEY pkDlkey, UINT32 nBitsPriv, UINT32 flags );8072//8073// Sets the number of bits that this dlkey can have in its private key8074// The set value is only used for when the dlkey is a named safe-prime dlgroup, otherwise the value8075// is ignored.8076//8077// Requirements:8078// - pkDlkey->pDlgroup->nBitsOfQ >= nBitsPriv >= pkDlkey->pDlgroup->nMinBitsPriv8079// Otherwise SYMCRYPT_INVALID_ARGUMENT is returned8080//8081// Allowed flags:8082// - None.80838084PCSYMCRYPT_DLGROUP8085SYMCRYPT_CALL8086SymCryptDlkeyGetGroup( _In_ PCSYMCRYPT_DLKEY pkDlkey );8087//8088// Returns a pointer to the dlgroup object associated with the key.8089//80908091UINT328092SYMCRYPT_CALL8093SymCryptDlkeySizeofPublicKey( _In_ PCSYMCRYPT_DLKEY pkDlkey );8094//8095// Returns the size in bytes of a blob big enough to retrieve the public key.8096//80978098UINT328099SYMCRYPT_CALL8100SymCryptDlkeySizeofPrivateKey( _In_ PCSYMCRYPT_DLKEY pkDlkey );8101//8102// Returns the size in bytes of a blob big enough to retrieve the private key.8103//81048105BOOLEAN8106SYMCRYPT_CALL8107SymCryptDlkeyHasPrivateKey( _In_ PCSYMCRYPT_DLKEY pkDlkey );8108//8109// Returns TRUE if the pkDlkey object has a private key set.8110//81118112SYMCRYPT_ERROR8113SYMCRYPT_CALL8114SymCryptDlkeyGenerate(8115_In_ UINT32 flags,8116_Inout_ PSYMCRYPT_DLKEY pkDlkey );8117//8118// Allowed flags:8119// - SYMCRYPT_FLAG_DLKEY_GEN_MODP8120// When set, generate a private key between 1 and P-2.8121// When Q is known, this overrides the default behavior of generating a private key between 1 and Q-1,8122// or 1 and min(2^nBitsPriv-1, Q-1) for named safe-prime groups8123// When Q is not known, this does not affect the behavior8124//8125// - SYMCRYPT_FLAG_KEY_NO_FIPS8126// Opt-out of performing validation required for FIPS8127//8128// - At least one of the flags indicating what the Dlkey is to be used for must be specified:8129// SYMCRYPT_FLAG_DLKEY_DSA8130// SYMCRYPT_FLAG_DLKEY_DH8131//8132// Note:8133// If SYMCRYPT_FLAG_DLKEY_GEN_MODP is specified then SYMCRYPT_FLAG_KEY_NO_FIPS must also be8134// specified to avoid SYMCRYPT_INVALID_ARGUMENT, as FIPS requires the default generation behavior8135//81368137SYMCRYPT_ERROR8138SYMCRYPT_CALL8139SymCryptDlkeySetValue(8140_In_reads_bytes_( cbPrivateKey ) PCBYTE pbPrivateKey,8141SIZE_T cbPrivateKey,8142_In_reads_bytes_( cbPublicKey ) PCBYTE pbPublicKey,8143SIZE_T cbPublicKey,8144SYMCRYPT_NUMBER_FORMAT numFormat,8145UINT32 flags,8146_Inout_ PSYMCRYPT_DLKEY pkDlkey );8147//8148// Import key material to a DLKEY object.8149//8150// Allowed flags:8151//8152// - SYMCRYPT_FLAG_KEY_NO_FIPS8153// Opt-out of performing validation required for FIPS8154//8155// - SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION8156// Opt-out of performing almost all validation - must be specified with SYMCRYPT_FLAG_KEY_NO_FIPS8157//8158// - At least one of the flags indicating what the Dlkey is to be used for must be specified:8159// SYMCRYPT_FLAG_DLKEY_DSA8160// SYMCRYPT_FLAG_DLKEY_DH8161//8162// Described in more detail in the "Flags for asymmetric key generation and import" section above8163//81648165SYMCRYPT_ERROR8166SYMCRYPT_CALL8167SymCryptDlkeyGetValue(8168_In_ PCSYMCRYPT_DLKEY pkDlkey,8169_Out_writes_bytes_( cbPrivateKey )8170PBYTE pbPrivateKey,8171SIZE_T cbPrivateKey,8172_Out_writes_bytes_( cbPublicKey )8173PBYTE pbPublicKey,8174SIZE_T cbPublicKey,8175SYMCRYPT_NUMBER_FORMAT numFormat,8176UINT32 flags );8177//8178// Retrieve the public or the private key (or both) from a DLKEY. The buffers should be8179// allocated by the caller.8180//81818182SYMCRYPT_ERROR8183SYMCRYPT_CALL8184SymCryptDlkeyExtendKeyUsage(8185_Inout_ PSYMCRYPT_DLKEY pkDlkey,8186UINT32 flags );8187//8188// Enable an existing key which has been generated or imported to be used in specified algorithms.8189// Some callers may not know at key generation or import time what algorithms a key will be used for8190// and this API allows the key to be extended for use in additional algorithms. Use of this API may8191// not be compliant with FIPS 140-3.8192//8193// - flags must be some bitwise OR of the following flags:8194// SYMCRYPT_FLAG_DLKEY_DSA8195// SYMCRYPT_FLAG_DLKEY_DH81968197//=====================================================8198// Elliptic curve operations and supported curves8199//82008201UINT328202SYMCRYPT_CALL8203SymCryptEcurvePrivateKeyDefaultFormat( _In_ PCSYMCRYPT_ECURVE pCurve );8204//8205// This function returns the private key default format of the input curve.8206//82078208UINT328209SYMCRYPT_CALL8210SymCryptEcurveHighBitRestrictionNumOfBits( _In_ PCSYMCRYPT_ECURVE pCurve );8211//8212// This function returns the number of bits specified by the high bit restriction8213// value of the input curve.8214//82158216UINT328217SYMCRYPT_CALL8218SymCryptEcurveHighBitRestrictionPosition( _In_ PCSYMCRYPT_ECURVE pCurve );8219//8220// This function returns the position of the high bit restriction8221// value of the input curve.8222//82238224UINT328225SYMCRYPT_CALL8226SymCryptEcurveHighBitRestrictionValue( _In_ PCSYMCRYPT_ECURVE pCurve );8227//8228// This function returns the high bit restriction value of the input curve.8229//82308231UINT328232SYMCRYPT_CALL8233SymCryptEcurveBitsizeofFieldModulus( _In_ PCSYMCRYPT_ECURVE pCurve );8234//8235// This function returns the number of bits of a field element on which8236// the curve is defined.8237//82388239UINT328240SYMCRYPT_CALL8241SymCryptEcurveBitsizeofGroupOrder( _In_ PCSYMCRYPT_ECURVE pCurve );8242//8243// This function returns the number of bits of the order of the subgroup generated by8244// the distinguished point of the curve.8245//82468247UINT328248SYMCRYPT_CALL8249SymCryptEcurveSizeofFieldElement( _In_ PCSYMCRYPT_ECURVE pCurve );8250//8251// This function returns the number of bytes of a field element. It is used to8252// construct buffers for setting and getting the value of elliptic curve points (most8253// notably the public key of an ECKEY object).8254//8255// The result is equal to the cbFieldLength field of the parameters that created the curve.8256//82578258UINT328259SYMCRYPT_CALL8260SymCryptEcurveSizeofScalarMultiplier( _In_ PCSYMCRYPT_ECURVE pCurve );8261//8262// This function returns the number of bytes of a scalar integer that is big enough to8263// store a private key (or a multiplier of an elliptic curve point). It is used to8264// construct buffers for setting and getting the value of a scalar multiplier (most8265// notably the private key of an ECKEY object - see SymCryptEckeySetValue and8266// SymCryptEckeyGetValue).8267//8268// The result is equal to sizeof( subgroupOrder * co-factor ).8269//82708271BOOLEAN8272SYMCRYPT_CALL8273SymCryptEcurveIsSame(8274_In_ PCSYMCRYPT_ECURVE pCurve1,8275_In_ PCSYMCRYPT_ECURVE pCurve2);8276//8277// Returns true if pCurve1 and pCurve2 have same type, P, A, and B - false otherwise.8278//8279// Note: This does not check that the curves have the same G set, callers may additionally8280// consider calling SymCryptEcpointIsEqual to compare the curves' distinguished points.8281//82828283// Internally supported curves8284extern const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsNistP192;8285extern const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsNistP224;8286extern const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsNistP256;8287extern const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsNistP384;8288extern const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsNistP521;82898290extern const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsNumsP256t1;8291extern const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsNumsP384t1;8292extern const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsNumsP512t1;82938294extern const PCSYMCRYPT_ECURVE_PARAMS SymCryptEcurveParamsCurve25519;82958296typedef enum _SYMCRYPT_ECURVE_ID8297{8298SYMCRYPT_ECURVE_ID_NULL = 0,8299SYMCRYPT_ECURVE_ID_NIST_P192 = 1,8300SYMCRYPT_ECURVE_ID_NIST_P224 = 2,8301SYMCRYPT_ECURVE_ID_NIST_P256 = 3,8302SYMCRYPT_ECURVE_ID_NIST_P384 = 4,8303SYMCRYPT_ECURVE_ID_NIST_P521 = 5,8304SYMCRYPT_ECURVE_ID_NUMS_P256T1 = 6,8305SYMCRYPT_ECURVE_ID_NUMS_P384T1 = 7,8306SYMCRYPT_ECURVE_ID_NUMS_P512T1 = 8,8307SYMCRYPT_ECURVE_ID_CURVE25519 = 98308} SYMCRYPT_ECURVE_ID;83098310PCSYMCRYPT_ECURVE_PARAMS8311SYMCRYPT_CALL8312SymCryptGetEcurveParams( SYMCRYPT_ECURVE_ID ecurveId );8313//8314// Returns a pointer to the elliptic curve parameters structure for the specified curve ID.8315// Returns NULL if the curve ID is invalid.8316//83178318//=====================================================8319// ECC flags8320//8321// Also see Generic key validation flags above83228323// SYMCRYPT_FLAG_ECDSA_NO_TRUNCATION: This flag applies only to the ECDSA algorithm. When set, the sign8324// and verify algorithms will not do hash truncation. The caller can use their own truncation method in such case.8325// (default: according to the ECDSA standard)8326#define SYMCRYPT_FLAG_ECDSA_NO_TRUNCATION (0x08)83278328//=====================================================8329// EC key operations83308331UINT328332SYMCRYPT_CALL8333SymCryptEckeySizeofPublicKey(8334_In_ PCSYMCRYPT_ECKEY pkEckey,8335_In_ SYMCRYPT_ECPOINT_FORMAT ecPointFormat );8336//8337// Returns the size in bytes of a blob big enough to retrieve the public key in8338// the specified ECPOINT format.8339//83408341UINT328342SYMCRYPT_CALL8343SymCryptEckeySizeofPrivateKey( _In_ PCSYMCRYPT_ECKEY pkEckey );8344//8345// Returns the size in bytes of a blob big enough to retrieve the private key.8346// It is equal to SymCryptEcurveSizeofScalarMultiplier( pCurve ) where pCurve is the8347// curve that created the key.8348//83498350BOOLEAN8351SYMCRYPT_CALL8352SymCryptEckeyHasPrivateKey( _In_ PCSYMCRYPT_ECKEY pkEckey );8353//8354// Returns TRUE if the pkEckey object has a private key set.8355//83568357SYMCRYPT_ERROR8358SYMCRYPT_CALL8359SymCryptEckeySetValue(8360_In_reads_bytes_( cbPrivateKey ) PCBYTE pbPrivateKey,8361SIZE_T cbPrivateKey,8362_In_reads_bytes_( cbPublicKey ) PCBYTE pbPublicKey,8363SIZE_T cbPublicKey,8364SYMCRYPT_NUMBER_FORMAT numFormat,8365SYMCRYPT_ECPOINT_FORMAT ecPointFormat,8366UINT32 flags,8367_Inout_ PSYMCRYPT_ECKEY pEckey );8368//8369// Import key material to an ECKEY object.8370//8371// Requirements:8372// (pbPrivateKey, cbPrivateKey): a buffer that contains the private key, encoded8373// in the format specified by the numFormat parameter.8374// Note that the integer encoded in (pbPrivateKey, cbPrivateKey) is taken modulo the order of the8375// subgroup generated by the curve generator. Callers that want a uniform private key value8376// should ensure that the input is uniform in the range [1..GOrd-1].8377//8378// Requirements: cbPrivateKey == SymCryptEckeySizeofPrivateKey( pEckey )8379//8380// If pbPrivateKey == NULL && cbPrivateKey == 0, then no private key is imported, and the8381// resulting ECKEY object will not have a private key.8382//8383// (pbPublicKey, cbPublicKey): buffer that contains the public key, encoded in the format8384// specified by the format parameter, the buffer length, and the curve properties.8385//8386// Requirements: cbPublicKey == SymCryptEckeySizeofPublicKey( pEckey, ecPointFormat )8387//8388// If no public key is presented (pbPublicKey == NULL && cbPublicKey == 0) then the public8389// key is computed from the provided private key.8390//8391// At least one of the public and private keys must be provided.8392//8393// If both are provided, then they must match.8394//8395// The algorithm always sets the corresponding public key8396//8397// Allowed flags:8398//8399// - SYMCRYPT_FLAG_KEY_NO_FIPS8400// Opt-out of performing validation required for FIPS8401//8402// - SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION8403// Opt-out of performing almost all validation - must be specified with SYMCRYPT_FLAG_KEY_NO_FIPS8404//8405// - At least one of the flags indicating what the Eckey is to be used for must be specified:8406// SYMCRYPT_FLAG_ECKEY_ECDSA8407// SYMCRYPT_FLAG_ECKEY_ECDH8408//8409// Described in more detail in the "Flags for asymmetric key generation and import" section above8410//84118412SYMCRYPT_ERROR8413SYMCRYPT_CALL8414SymCryptEckeySetRandom(8415_In_ UINT32 flags,8416_Inout_ PSYMCRYPT_ECKEY pEckey );8417//8418// Generates a new Eckey public/private key pair using the specified curve. The public key8419// is a uniformly random non-zero point of the subgroup generated by the distinguished point8420// of the curve. This complies with the FIPS 186-4 standard.8421//8422// Remarks:8423// - In the case that the highbit restrictions on the curve are unsatisfiable, i.e.8424// there is no private key smaller than the group order it returns8425// SYMCRYPT_INVALID_ARGUMENT.8426//8427// Allowed flags:8428//8429// - SYMCRYPT_FLAG_KEY_NO_FIPS8430// Opt-out of performing validation required for FIPS8431//8432// - At least one of the flags indicating what the Eckey is to be used for must be specified:8433// SYMCRYPT_FLAG_ECKEY_ECDSA8434// SYMCRYPT_FLAG_ECKEY_ECDH84358436// Described in more detail in the "Flags for asymmetric key generation and import" section above8437//84388439SYMCRYPT_ERROR8440SYMCRYPT_CALL8441SymCryptEckeyGetValue(8442_In_ PCSYMCRYPT_ECKEY pEckey,8443_Out_writes_bytes_( cbPrivateKey )8444PBYTE pbPrivateKey,8445SIZE_T cbPrivateKey,8446_Out_writes_bytes_( cbPublicKey )8447PBYTE pbPublicKey,8448SIZE_T cbPublicKey,8449SYMCRYPT_NUMBER_FORMAT numFormat,8450SYMCRYPT_ECPOINT_FORMAT ecPointFormat,8451UINT32 flags );8452//8453// Retrieve the public or the private key (or both) from an ECKEY. The buffers should be8454// allocated by the caller.8455//8456// If (pbPrivateKey != NULL), then the function will return the private key in pbPrivateKey8457// in the format specified by the numFormat parameter **as long as** the following three8458// requirements are satisfied:8459// 1. cbPrivateKey >= SymCryptEckeySizeofPrivateKey( pEckey )8460// 2. pEckey contains a private key part (If this fails the function returns SYMCRYPT_INVALID_BLOB)8461// If (pbPrivateKey == NULL) and (cbPrivateKey == 0), then these parameters are ignored8462// and no private key is returned.8463//8464// If (pbPublicKey != NULL), then the function will return the public key in pbPublicKey8465// in the format specified by the numFormat and the ecPointFormat parameters8466// **as long as** the following requirement is satisfied:8467// 1. cbPublicKey >= SymCryptEckeySizeofPublicKey( pEckey, ecPointFormat )8468// If (pbPublicKey == NULL) and (cbPublicKey == 0), then these parameters are ignored8469// and no public key is returned.8470//8471// Allowed flags:8472// - None.8473//84748475SYMCRYPT_ERROR8476SYMCRYPT_CALL8477SymCryptEckeyExtendKeyUsage(8478_Inout_ PSYMCRYPT_ECKEY pEckey,8479UINT32 flags );8480//8481// Enable an existing key which has been generated or imported to be used in specified algorithms.8482// Some callers may not know at key generation or import time what algorithms a key will be used for8483// and this API allows the key to be extended for use in additional algorithms. Use of this API may8484// not be compliant with FIPS 140-38485//8486// - flags must be some bitwise OR of the following flags:8487// SYMCRYPT_FLAG_ECKEY_ECDSA8488// SYMCRYPT_FLAG_ECKEY_ECDH84898490/************************8491* Crypto algorithm API *8492************************/84938494//8495// The Crypto algorithm API implements various cryptographic algorithms that use large-integer arithmetic.8496//84978498//8499// RSA Encryption Algorithms8500//85018502SYMCRYPT_ERROR8503SYMCRYPT_CALL8504SymCryptRsaRawEncrypt(8505_In_ PCSYMCRYPT_RSAKEY pkRsakey,8506_In_reads_bytes_( cbSrc ) PCBYTE pbSrc,8507SIZE_T cbSrc,8508SYMCRYPT_NUMBER_FORMAT numFormat,8509UINT32 flags,8510_Out_writes_( cbDst ) PBYTE pbDst,8511SIZE_T cbDst );8512//8513// This function encrypts the buffer pbSrc (of size cbSrc bytes) under the pkRsakey key using textbook RSA.8514// The output is stored in the pbDst buffer (of size cbDst bytes).8515// For in place encryption pbSrc = pbDst.8516//8517// Both input and output buffers store a number in the number format numFormat.8518//8519// Requirements:8520// - If cbDst is too small for the result then SYMCRYPT_BUFFER_TOO_SMALL is returned.8521// Safe size is cbDst = SymCryptRsakeySizeofModulus(pkRsakey).8522// - The number stored in the pbSrc buffer must be strictly smaller than the value8523// of the public modulus in pkRsakey.8524//8525// Allowed flags:8526// None8527//85288529SYMCRYPT_ERROR8530SYMCRYPT_CALL8531SymCryptRsaRawDecrypt(8532_In_ PCSYMCRYPT_RSAKEY pkRsakey,8533_In_reads_bytes_( cbSrc ) PCBYTE pbSrc,8534SIZE_T cbSrc,8535SYMCRYPT_NUMBER_FORMAT numFormat,8536UINT32 flags,8537_Out_writes_( cbDst ) PBYTE pbDst,8538SIZE_T cbDst );8539//8540// This function decrypts the buffer pbSrc (of size cbSrc bytes) with the pkRsakey key using textbook RSA.8541// The output is stored in the pbDst buffer (of size cbDst bytes).8542// For in place decryption pbSrc = pbDst.8543//8544// Both input and output buffers store a number in the number format numFormat.8545//8546// Requirements:8547// - If cbDst is too small for the result then SYMCRYPT_BUFFER_TOO_SMALL is returned.8548// Safe size is cbDst = SymCryptRsakeySizeofModulus(pkRsakey).8549// - The number stored in the pbSrc buffer must be strictly smaller than the value8550// of the public modulus in pkRsakey.8551// - The RSAKEY pkRsakey must have a private key part. Otherwise SYMCRYPT_INVALID_ARGUMENT is returned.8552//8553// Allowed flags:8554// None8555//85568557SYMCRYPT_ERROR8558SYMCRYPT_CALL8559SymCryptRsaPkcs1Encrypt(8560_In_ PCSYMCRYPT_RSAKEY pkRsakey,8561_In_reads_bytes_( cbSrc ) PCBYTE pbSrc,8562SIZE_T cbSrc,8563UINT32 flags,8564SYMCRYPT_NUMBER_FORMAT nfDst,8565_Out_writes_opt_( cbDst ) PBYTE pbDst,8566SIZE_T cbDst,8567_Out_ SIZE_T *pcbDst );8568//8569// This function encrypts the buffer pbSrc under the pkRsakey key using RSA PKCS1 v1.5.8570// The output is stored in the pbDst buffer and the number of bytes written in *pcbDst.8571//8572// If pbDst == NULL then only the *pcbDst is output.8573//8574// nfDst is the number format of the ciphertext (i.e. the pbDst buffer).8575//8576// Allowed flags:8577// None8578//85798580SYMCRYPT_ERROR8581SYMCRYPT_CALL8582SymCryptRsaPkcs1Decrypt(8583_In_ PCSYMCRYPT_RSAKEY pkRsakey,8584_In_reads_bytes_( cbSrc ) PCBYTE pbSrc,8585SIZE_T cbSrc,8586SYMCRYPT_NUMBER_FORMAT nfSrc,8587UINT32 flags,8588_Out_writes_opt_( cbDst ) PBYTE pbDst,8589SIZE_T cbDst,8590_Out_ SIZE_T *pcbDst );8591//8592// Perform an RSA-PKCS1 decryption.8593// - pbSrc/cbSrc: source buffer8594// - nfSrc: format of source buffer8595// - flags: must be 08596// - pbDst/cbDst: destination buffer8597// - pcbDst: receives the size of the decrypted data.8598//8599// If the data in improperly formatted, an error is returned.8600// If pbDst == NULL, then *pcbDst is set to the decrypted data length, and the functions succeeds.8601// This is not recommended as retrieving the actual data requires a second RSA decryption,8602// which is expensive. We recommend that callers provide a large enough buffer the first time.8603// If pbDst != NULL and cbDst is too small, then *pcbDst is set to the required size of pbDst8604// and SYMCRYPT_BUFFER_TOO_SMALL is returned.8605//8606// Allowed flags:8607// None8608//86098610SYMCRYPT_ERROR8611SYMCRYPT_CALL8612SymCryptRsaOaepEncrypt(8613_In_ PCSYMCRYPT_RSAKEY pkRsakey,8614_In_reads_bytes_( cbSrc ) PCBYTE pbSrc,8615SIZE_T cbSrc,8616_In_ PCSYMCRYPT_HASH hashAlgorithm,8617_In_reads_bytes_( cbLabel ) PCBYTE pbLabel,8618SIZE_T cbLabel,8619UINT32 flags,8620SYMCRYPT_NUMBER_FORMAT nfDst,8621_Out_writes_opt_( cbDst ) PBYTE pbDst,8622SIZE_T cbDst,8623_Out_ SIZE_T *pcbDst );8624//8625// This function encrypts the buffer pbSrc under the pkRsakey key using RSA OAEP.8626// The output is stored in the pbDst buffer and the number of bytes written in *pcbDst.8627//8628// If pbDst == NULL then only the *pcbDst is output.8629//8630// nfDst is the number format of the ciphertext (i.e. the pbDst buffer).8631//8632// Allowed flags:8633// None8634//86358636SYMCRYPT_ERROR8637SYMCRYPT_CALL8638SymCryptRsaOaepDecrypt(8639_In_ PCSYMCRYPT_RSAKEY pkRsakey,8640_In_reads_bytes_( cbSrc ) PCBYTE pbSrc,8641SIZE_T cbSrc,8642SYMCRYPT_NUMBER_FORMAT nfSrc,8643_In_ PCSYMCRYPT_HASH hashAlgorithm,8644_In_reads_bytes_( cbLabel ) PCBYTE pbLabel,8645SIZE_T cbLabel,8646UINT32 flags,8647_Out_writes_opt_( cbDst ) PBYTE pbDst,8648SIZE_T cbDst,8649_Out_ SIZE_T *pcbDst );8650//8651// This function decrypts the buffer pbSrc with the pkRsakey key using RSA OAEP.8652// The output is stored in the pbDst buffer and the number of bytes written in *pcbDst.8653//8654// If pbDst == NULL then only the *pcbDst is output.8655//8656// nfSrc is the number format of the ciphertext (i.e. the pbSrc buffer).8657//8658// Requirement:8659// - cbSrc <= SymCryptRsakeySizeofModulus( pkRsakey ). Otherwise the function8660// returns SYMCRYPT_INVALID_ARGUMENT.8661//8662// Allowed flags:8663// None8664//86658666//8667// RSA Signing Algorithms8668//86698670#define SYMCRYPT_FLAG_RSA_PKCS1_NO_ASN1 (0x01)8671#define SYMCRYPT_FLAG_RSA_PKCS1_OPTIONAL_HASH_OID (0x02)86728673#define SYMCRYPT_FLAG_RSA_PSS_VERIFY_WITH_MINIMUM_SALT (0x04)86748675//8676// SYMCRYPT_FLAG_RSA_PKCS1_NO_ASN1: For RSA PKCS1 to not use the OID on signing or verifying.8677//86788679SYMCRYPT_ERROR8680SYMCRYPT_CALL8681SymCryptRsaPkcs1Sign(8682_In_ PCSYMCRYPT_RSAKEY pkRsakey,8683_In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,8684SIZE_T cbHashValue,8685_In_ PCSYMCRYPT_OID pHashOIDs,8686_In_ SIZE_T nOIDCount,8687UINT32 flags,8688SYMCRYPT_NUMBER_FORMAT nfSignature,8689_Out_writes_opt_( cbSignature ) PBYTE pbSignature,8690SIZE_T cbSignature,8691_Out_ SIZE_T *pcbSignature );8692//8693// This function signs a message (its hash value is stored in pbHashValue) with8694// the pkRsakey key using RSA PKCS1 v1.5. The signature is stored in the pbSignature8695// buffer and the number of bytes written in *pcbSignature.8696//8697// pHashOIDs points to an array of SYMCRYPT_OID and the array size is nOIDCount8698//8699// If pbSignature == NULL then only the *pcbSignature is output.8700//8701// nfSignature is the number format of the signature (i.e. the pbSignature buffer). Currently8702// only SYMCRYPT_NUMBER_FORMAT_MSB_FIRST is supported.8703//8704// Allowed flags:8705// SYMCRYPT_FLAG_RSA_PKCS1_NO_ASN18706//87078708SYMCRYPT_ERROR8709SYMCRYPT_CALL8710SymCryptRsaPkcs1Verify(8711_In_ PCSYMCRYPT_RSAKEY pkRsakey,8712_In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,8713SIZE_T cbHashValue,8714_In_reads_bytes_( cbSignature ) PCBYTE pbSignature,8715SIZE_T cbSignature,8716SYMCRYPT_NUMBER_FORMAT nfSignature,8717_In_reads_opt_( nOIDCount ) PCSYMCRYPT_OID pHashOID,8718_In_ SIZE_T nOIDCount,8719UINT32 flags );8720//8721// This function verifies the signature of a message (its hash value is input in8722// pbHashValue) with the pkRsakey key using RSA PKCS1 v1.5. The signature is input8723// in the pbSignature buffer.8724//8725// pHashOIDs points to an array of SYMCRYPT_OID and the array size is nOIDCount8726//8727// It returns SYMCRYPT_NO_ERROR if the verification succeeded or SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE8728// if it failed.8729//8730// nfSignature is the number format of the signature (i.e. the pbSignature buffer). Currently8731// only SYMCRYPT_NUMBER_FORMAT_MSB_FIRST is supported.8732//8733// Allowed flags:8734// SYMCRYPT_FLAG_RSA_PKCS1_OPTIONAL_HASH_OID8735//8736// When the flag is set, this function will do signature verification by not using hash OID when needed8737//873887398740SYMCRYPT_ERROR8741SYMCRYPT_CALL8742SymCryptRsaPssSign(8743_In_ PCSYMCRYPT_RSAKEY pkRsakey,8744_In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,8745SIZE_T cbHashValue,8746_In_ PCSYMCRYPT_HASH hashAlgorithm,8747SIZE_T cbSalt,8748UINT32 flags,8749SYMCRYPT_NUMBER_FORMAT nfSignature,8750_Out_writes_opt_( cbSignature ) PBYTE pbSignature,8751SIZE_T cbSignature,8752_Out_ SIZE_T *pcbSignature );8753//8754// Sign a message using RSA-PSS8755// - pkRsaKey: Key to sign with; must contain a private key8756// - pbHashValue/cbHashValue: Value to sign8757// - hashAlgorithm: Hash algorithm to use in the MGF of PSS8758// - cbSalt: # bytes of salt to use (typically equal to size of hash value)8759// - flags: must be 08760// - nfSignature: Number format of signature. Typically SYMCRYPT_NUMBER_FORMAT_MSB_FIRST8761// - pbSignature/cbSignature: buffer that receives the signature.8762// If pbSignature == NULL< only *pcbSignature is returned.8763// Note: pbSignature receives an integer, so if the buffer is larger than the modulus size8764// it will be padded with zeroes. For MSB-first format the zeroes are at the start of the buffer.8765// Typically this buffer is the same size as the RSA modulus.8766// - pcbSignature: receives the size of the signature.8767//8768// Return value:8769// If cbHashValue + cbSalt is too large (above modulus size minus 2 or 3 depending on details) then8770// signature generation fails.8771//8772// Allowed flags:8773// None8774//87758776SYMCRYPT_ERROR8777SYMCRYPT_CALL8778SymCryptRsaPssVerify(8779_In_ PCSYMCRYPT_RSAKEY pkRsakey,8780_In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,8781SIZE_T cbHashValue,8782_In_reads_bytes_( cbSignature ) PCBYTE pbSignature,8783SIZE_T cbSignature,8784SYMCRYPT_NUMBER_FORMAT nfSignature,8785_In_ PCSYMCRYPT_HASH hashAlgorithm,8786SIZE_T cbSalt,8787UINT32 flags );8788//8789// This function verifies the signature of a message (its hash value is input in8790// pbHashValue) with the pkRsakey key using RSA PSS. The signature is input8791// in the pbSignature buffer.8792//8793// It returns SYMCRYPT_NO_ERROR if the verification succeeded or SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE8794// if it failed.8795//8796// nfSignature is the number format of the signature (i.e. the pbSignature buffer). Currently8797// only SYMCRYPT_NUMBER_FORMAT_MSB_FIRST is supported.8798//8799// Requirements:8800// - cbHashValue <= SymCryptRsakeySizeofModulus( pkRsakey )8801// - cbSalt <= SymCryptRsakeySizeofModulus( pkRsakey )8802// - cbSignature <= SymCryptRsakeySizeofModulus( pkRsakey )8803//8804// Allowed flags:8805// SYMCRYPT_FLAG_RSA_PSS_VERIFY_WITH_MINIMUM_SALT8806//8807// When the flag is set, this function will do signature verification using the cbSalt parameter as8808// a minimum value for the salt length, rather than using it as an exact value. Specifying this and8809// setting cbSalt = 0 allows callers to verify a signature which has a valid encoding with any salt8810// length using a single call.8811//88128813VOID8814SYMCRYPT_CALL8815SymCryptRsaSelftest(void);8816//8817// FIPS self-test for RSA sign/verify. This function uses a hardcoded key to perform the self-test8818// without having to generate a key. If the self-test fails, SymCryptFatal will be called to8819// fastfail.8820// The self-test will automatically be performed before first operational use of RSA if using a key8821// with FIPS validation, so most callers should never use this function.8822//882388248825//8826// DSA8827//88288829SYMCRYPT_ERROR8830SYMCRYPT_CALL8831SymCryptDsaSign(8832_In_ PCSYMCRYPT_DLKEY pKey,8833_In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,8834SIZE_T cbHashValue,8835SYMCRYPT_NUMBER_FORMAT format,8836UINT32 flags,8837_Out_writes_bytes_( cbSignature ) PBYTE pbSignature,8838SIZE_T cbSignature );8839//8840// Sign a message using the DSA signature algorithm.8841// (pbHashValue,cbHashValue) is the output of the hash function that hashed the message to be signed.8842// (pbSignature,cbSignature) is the output buffer that receives the signature.8843// The signature is encoded as two integers (R,S) mod Q in the format specified by the 'format' parameter.8844//8845// Allowed flags:8846// None8847//884888498850SYMCRYPT_ERROR8851SYMCRYPT_CALL8852SymCryptDsaVerify(8853_In_ PCSYMCRYPT_DLKEY pKey,8854_In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,8855SIZE_T cbHashValue,8856_In_reads_bytes_( cbSignature ) PCBYTE pbSignature,8857SIZE_T cbSignature,8858SYMCRYPT_NUMBER_FORMAT format,8859UINT32 flags );8860//8861// Verifies a DSA signature using the public part of Key.8862//8863// It returns SYMCRYPT_NO_ERROR if the verification succeeded or SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE8864// if it failed.8865//8866// Allowed flags:8867// None8868//88698870VOID8871SYMCRYPT_CALL8872SymCryptDsaSelftest(void);8873//8874// FIPS self-test for DSA sign/verify. This function uses a hardcoded key to perform the self-test8875// without having to generate a key. If the self-test fails, SymCryptFatal will be called to8876// fastfail.8877// The self-test will automatically be performed before first operational use of DSA if using a key8878// with FIPS validation, so most callers should never use this function.8879//88808881//8882// DH8883//88848885SYMCRYPT_ERROR8886SYMCRYPT_CALL8887SymCryptDhSecretAgreement(8888_In_ PCSYMCRYPT_DLKEY pkPrivate,8889_In_ PCSYMCRYPT_DLKEY pkPublic,8890SYMCRYPT_NUMBER_FORMAT format,8891UINT32 flags,8892_Out_writes_( cbAgreedSecret ) PBYTE pbAgreedSecret,8893SIZE_T cbAgreedSecret );8894//8895// Calculates the agreed secret of a DH key exchange and stores it8896// in the pbAgreedSecret buffer under the specified number format.8897//8898// format is the number format of the agreed secret (pbAgreedSecret buffer).8899//8900// Allowed flags:8901// - None8902//89038904VOID8905SYMCRYPT_CALL8906SymCryptDhSecretAgreementSelftest(void);8907//8908// FIPS self-test for DH secret agreement. This function uses two hardcoded keys and a precalculated8909// known answer to perform the self-test without having to generate a key. If the self-test fails,8910// SymCryptFatal will be called to fastfail.8911// The self-test will automatically be performed before first operational use of DH if using keys8912// with FIPS validation, so most callers should never use this function.8913//89148915//8916// For both ECDSA and ECDH algorithms the key generation and management is the same. The main algorithms are:8917// - SymCryptEckeyAllocate or SymCryptEckeyCreate for creation of the ECKEY object.8918// - SymCryptEckeySetValue or SymCryptEckeySetRandom for filling the key with the preferred key material.8919// - SymCryptEckeyFree or SymCryptEckeyWipe for freeing or wiping the key.8920//89218922//8923// ECDSA8924//89258926SYMCRYPT_ERROR8927SYMCRYPT_CALL8928SymCryptEcDsaSign(8929_In_ PCSYMCRYPT_ECKEY pKey,8930_In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,8931SIZE_T cbHashValue,8932SYMCRYPT_NUMBER_FORMAT format,8933UINT32 flags,8934_Out_writes_bytes_( cbSignature ) PBYTE pbSignature,8935SIZE_T cbSignature );8936//8937// Sign a message using the ECDSA signature algorithm.8938// (pbHashValue,cbHashValue) is the output of the hash function that hashed the message to be signed.8939// (pbSignature,cbSignature) is the output buffer that receives the signature.8940// The signature is encoded as two integers in the format specified by the 'format' parameter.8941//8942// Allowed flags:8943// SYMCRYPT_FLAG_ECDSA_NO_TRUNCATION: If set then the hash value will8944// not be truncated.8945//89468947SYMCRYPT_ERROR8948SYMCRYPT_CALL8949SymCryptEcDsaVerify(8950_In_ PCSYMCRYPT_ECKEY pKey,8951_In_reads_bytes_( cbHashValue ) PCBYTE pbHashValue,8952SIZE_T cbHashValue,8953_In_reads_bytes_( cbSignature ) PCBYTE pbSignature,8954SIZE_T cbSignature,8955SYMCRYPT_NUMBER_FORMAT format,8956UINT32 flags );89578958//8959// Verifies an ECDSA signature using the public part of Key.8960//8961// It returns SYMCRYPT_NO_ERROR if the verification succeeded or SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE8962// if it failed.8963//8964// Allowed flags:8965// SYMCRYPT_FLAG_ECDSA_NO_TRUNCATION: If set then the hash value will8966// not be truncated.89678968VOID8969SYMCRYPT_CALL8970SymCryptEcDsaSelftest(void);8971//8972// FIPS self-test for ECDSA sign/verify. This function uses a hardcoded key to perform the self-test8973// without having to generate a key. If the self-test fails, SymCryptFatal will be called to8974// fastfail.8975// The self-test will automatically be performed before first operational use of ECDSA if using a8976// key with FIPS validation, so most callers should never use this function.8977//89788979//8980// ECDH8981//89828983SYMCRYPT_ERROR8984SYMCRYPT_CALL8985SymCryptEcDhSecretAgreement(8986_In_ PCSYMCRYPT_ECKEY pkPrivate,8987_In_ PCSYMCRYPT_ECKEY pkPublic,8988SYMCRYPT_NUMBER_FORMAT format,8989UINT32 flags,8990_Out_writes_( cbAgreedSecret ) PBYTE pbAgreedSecret,8991SIZE_T cbAgreedSecret );89928993//8994// Calculates the agreed secret of a DH key exchange and stores it8995// in the pbAgreedSecret buffer under the specified number format.8996//8997// Allowed flags:8998// - None8999//90009001VOID9002SYMCRYPT_CALL9003SymCryptEcDhSecretAgreementSelftest(void);9004//9005// FIPS self-test for ECDH secret agreement. This function uses two hardcoded keys and a9006// precalculated known answer to perform the self-test without having to generate a key. If the9007// self-test fails, SymCryptFatal will be called to fastfail.9008// The self-test will automatically be performed before first operational use of ECDH if using keys9009// with FIPS validation, so most callers should never use this function.9010//90119012//========================================================================9013//9014// Stateful Hash-based Signatures9015//9016// Hash-based signature schemes are digital signature schemes built out of hash9017// functions. Stateful hash-based signatures are many-time signature schemes9018// composed of a one-time-signature (OTS) scheme and a Merkle-tree representing9019// multiple OTS with a public root value. At each signing operation, one of the9020// (unused) OTS keys is used to sign the message, and the private key is updated9021// so that the same OTS is not used again. Because there is a limited number of9022// OTS keys determined at key generation time, signing cannot be performed after9023// all OTSs are used. This is an important distinction from other digital signature9024// schemes such as RSA or ECDSA.9025//9026// It is crucial for the security of the *stateful* hash-based signatures that the9027// same private key state NOT be used more than once to sign messages, otherwise all9028// security is lost.9029//903090319032//========================================================================9033// XMSS API9034//9035// XMSS is a stateful hash-based signature scheme specified in RFC 8391. The9036// multi-tree variant is named XMSS^MT.9037//9038// XMSS uses WOTS+ as the one-time-signature (OTS) scheme. Public key consists9039// of two parts; Merkle-tree hash of OTS public keys called the Root, and a Seed value9040// used in in hash computations. The private key consists of SK_XMSS which is9041// used to deterministically create OTS keys, SK_PRF which is used to generate9042// the randomizer for hashing, and an integer Idx is used to select the next OTS key9043// for signing.9044//90459046typedef enum _SYMCRYPT_XMSS_ALGID9047{9048// Hash Fn. RFC-8391 SP800-2089049SYMCRYPT_XMSS_SHA2_10_256 = 0x00000001, // SHA-256 X X9050SYMCRYPT_XMSS_SHA2_16_256 = 0x00000002, // SHA-256 X X9051SYMCRYPT_XMSS_SHA2_20_256 = 0x00000003, // SHA-256 X X9052SYMCRYPT_XMSS_SHA2_10_512 = 0x00000004, // SHA-512 X9053SYMCRYPT_XMSS_SHA2_16_512 = 0x00000005, // SHA-512 X9054SYMCRYPT_XMSS_SHA2_20_512 = 0x00000006, // SHA-512 X9055SYMCRYPT_XMSS_SHAKE_10_256 = 0x00000007, // SHAKE128 X9056SYMCRYPT_XMSS_SHAKE_16_256 = 0x00000008, // SHAKE128 X9057SYMCRYPT_XMSS_SHAKE_20_256 = 0x00000009, // SHAKE128 X9058SYMCRYPT_XMSS_SHAKE_10_512 = 0x0000000A, // SHAKE256 X9059SYMCRYPT_XMSS_SHAKE_16_512 = 0x0000000B, // SHAKE256 X9060SYMCRYPT_XMSS_SHAKE_20_512 = 0x0000000C, // SHAKE256 X9061SYMCRYPT_XMSS_SHA2_10_192 = 0x0000000D, // SHA-256 X9062SYMCRYPT_XMSS_SHA2_16_192 = 0x0000000E, // SHA-256 X9063SYMCRYPT_XMSS_SHA2_20_192 = 0x0000000F, // SHA-256 X9064SYMCRYPT_XMSS_SHAKE256_10_256 = 0x00000010, // SHAKE256 X9065SYMCRYPT_XMSS_SHAKE256_16_256 = 0x00000011, // SHAKE256 X9066SYMCRYPT_XMSS_SHAKE256_20_256 = 0x00000012, // SHAKE256 X9067SYMCRYPT_XMSS_SHAKE256_10_192 = 0x00000013, // SHAKE256 X9068SYMCRYPT_XMSS_SHAKE256_16_192 = 0x00000014, // SHAKE256 X9069SYMCRYPT_XMSS_SHAKE256_20_192 = 0x00000015, // SHAKE256 X90709071} SYMCRYPT_XMSS_ALGID;90729073typedef enum _SYMCRYPT_XMSSMT_ALGID9074{9075// Hash Fn. RFC-8391 SP800-2089076// SHA-256 X X9077SYMCRYPT_XMSSMT_SHA2_20_2_256 = 0x00000001,9078SYMCRYPT_XMSSMT_SHA2_20_4_256 = 0x00000002,9079SYMCRYPT_XMSSMT_SHA2_40_2_256 = 0x00000003,9080SYMCRYPT_XMSSMT_SHA2_40_4_256 = 0x00000004,9081SYMCRYPT_XMSSMT_SHA2_40_8_256 = 0x00000005,9082SYMCRYPT_XMSSMT_SHA2_60_3_256 = 0x00000006,9083SYMCRYPT_XMSSMT_SHA2_60_6_256 = 0x00000007,9084SYMCRYPT_XMSSMT_SHA2_60_12_256 = 0x00000008,90859086// SHA-512 X9087SYMCRYPT_XMSSMT_SHA2_20_2_512 = 0x00000009,9088SYMCRYPT_XMSSMT_SHA2_20_4_512 = 0x0000000A,9089SYMCRYPT_XMSSMT_SHA2_40_2_512 = 0x0000000B,9090SYMCRYPT_XMSSMT_SHA2_40_4_512 = 0x0000000C,9091SYMCRYPT_XMSSMT_SHA2_40_8_512 = 0x0000000D,9092SYMCRYPT_XMSSMT_SHA2_60_3_512 = 0x0000000E,9093SYMCRYPT_XMSSMT_SHA2_60_6_512 = 0x0000000F,9094SYMCRYPT_XMSSMT_SHA2_60_12_512 = 0x00000010,90959096// SHAKE128 X9097SYMCRYPT_XMSSMT_SHAKE_20_2_256 = 0x00000011,9098SYMCRYPT_XMSSMT_SHAKE_20_4_256 = 0x00000012,9099SYMCRYPT_XMSSMT_SHAKE_40_2_256 = 0x00000013,9100SYMCRYPT_XMSSMT_SHAKE_40_4_256 = 0x00000014,9101SYMCRYPT_XMSSMT_SHAKE_40_8_256 = 0x00000015,9102SYMCRYPT_XMSSMT_SHAKE_60_3_256 = 0x00000016,9103SYMCRYPT_XMSSMT_SHAKE_60_6_256 = 0x00000017,9104SYMCRYPT_XMSSMT_SHAKE_60_12_256 = 0x00000018,91059106// SHAKE256 X9107SYMCRYPT_XMSSMT_SHAKE_20_2_512 = 0x00000019,9108SYMCRYPT_XMSSMT_SHAKE_20_4_512 = 0x0000001A,9109SYMCRYPT_XMSSMT_SHAKE_40_2_512 = 0x0000001B,9110SYMCRYPT_XMSSMT_SHAKE_40_4_512 = 0x0000001C,9111SYMCRYPT_XMSSMT_SHAKE_40_8_512 = 0x0000001D,9112SYMCRYPT_XMSSMT_SHAKE_60_3_512 = 0x0000001E,9113SYMCRYPT_XMSSMT_SHAKE_60_6_512 = 0x0000001F,9114SYMCRYPT_XMSSMT_SHAKE_60_12_512 = 0x00000020,91159116// SHA-256 X9117SYMCRYPT_XMSSMT_SHA2_20_2_192 = 0x00000021,9118SYMCRYPT_XMSSMT_SHA2_20_4_192 = 0x00000022,9119SYMCRYPT_XMSSMT_SHA2_40_2_192 = 0x00000023,9120SYMCRYPT_XMSSMT_SHA2_40_4_192 = 0x00000024,9121SYMCRYPT_XMSSMT_SHA2_40_8_192 = 0x00000025,9122SYMCRYPT_XMSSMT_SHA2_60_3_192 = 0x00000026,9123SYMCRYPT_XMSSMT_SHA2_60_6_192 = 0x00000027,9124SYMCRYPT_XMSSMT_SHA2_60_12_192 = 0x00000028,91259126// SHAKE256 X9127SYMCRYPT_XMSSMT_SHAKE256_20_2_256 = 0x00000029,9128SYMCRYPT_XMSSMT_SHAKE256_20_4_256 = 0x0000002A,9129SYMCRYPT_XMSSMT_SHAKE256_40_2_256 = 0x0000002B,9130SYMCRYPT_XMSSMT_SHAKE256_40_4_256 = 0x0000002C,9131SYMCRYPT_XMSSMT_SHAKE256_40_8_256 = 0x0000002D,9132SYMCRYPT_XMSSMT_SHAKE256_60_3_256 = 0x0000002E,9133SYMCRYPT_XMSSMT_SHAKE256_60_6_256 = 0x0000002F,9134SYMCRYPT_XMSSMT_SHAKE256_60_12_256 = 0x00000030,91359136// SHAKE256 X9137SYMCRYPT_XMSSMT_SHAKE256_20_2_192 = 0x00000031,9138SYMCRYPT_XMSSMT_SHAKE256_20_4_192 = 0x00000032,9139SYMCRYPT_XMSSMT_SHAKE256_40_2_192 = 0x00000033,9140SYMCRYPT_XMSSMT_SHAKE256_40_4_192 = 0x00000034,9141SYMCRYPT_XMSSMT_SHAKE256_40_8_192 = 0x00000035,9142SYMCRYPT_XMSSMT_SHAKE256_60_3_192 = 0x00000036,9143SYMCRYPT_XMSSMT_SHAKE256_60_6_192 = 0x00000037,9144SYMCRYPT_XMSSMT_SHAKE256_60_12_192 = 0x00000038,91459146} SYMCRYPT_XMSSMT_ALGID;914791489149typedef enum _SYMCRYPT_XMSSKEY_TYPE9150{9151SYMCRYPT_XMSSKEY_TYPE_NONE = 0,9152SYMCRYPT_XMSSKEY_TYPE_PUBLIC = 1, // Key object contains only public key9153SYMCRYPT_XMSSKEY_TYPE_PRIVATE = 2, // Key object contains both public key and private key9154} SYMCRYPT_XMSSKEY_TYPE;915591569157SYMCRYPT_ERROR9158SYMCRYPT_CALL9159SymCryptXmssParamsFromAlgId(9160SYMCRYPT_XMSS_ALGID id,9161_Out_ PSYMCRYPT_XMSS_PARAMS pParams);9162//9163// Populate SYMCRYPT_XMSS_PARAMS structure for the specified XMSS algorithm identifier9164// using the predefined parameter sets from RFC 8391 and NIST SP800-2089165//91669167SYMCRYPT_ERROR9168SYMCRYPT_CALL9169SymCryptXmssMtParamsFromAlgId(9170SYMCRYPT_XMSSMT_ALGID id,9171_Out_ PSYMCRYPT_XMSS_PARAMS pParams);9172//9173// Populate SYMCRYPT_XMSS_PARAMS structure for the specified XMSS^MT algorithm identifier9174// using the predefined parameter sets from RFC 8391 and NIST SP800-2089175//91769177SYMCRYPT_ERROR9178SYMCRYPT_CALL9179SymCryptXmssSetParams(9180_Out_ PSYMCRYPT_XMSS_PARAMS pParams,9181UINT32 id, // algorithm identifier9182_In_ PCSYMCRYPT_HASH pHash, // hash algorithm9183UINT32 cbHashOutput, // hash output size9184UINT32 nWinternitzWidth, // Winternitz parameter (width of digits)9185UINT32 nTotalTreeHeight, // total tree height9186UINT32 nLayers, // number of levels9187UINT32 cbPrefix // domain separator prefix length9188);9189//9190// Populates SYMCRYPT_XMSS_PARAMS structure by user defined parameters9191//9192//9193// Parameters:9194//9195// pParams. Pointer to the structure that will be populated with the9196// supplied parameters.9197//9198// id. Algorithm identifier, will be embedded in key and signature objects.9199//9200// pHash. Pointer to a hash object that implements a hash function which9201// will be used in XMSS/XMSS^MT operations.9202//9203// cbHashOutput. Output size of the hash function in bytes. Leading cbHashOutput9204// bytes are taken as hash output if the hash algorithm's actual output size is larger.9205//9206// nWinternitzWidth. Winternitz parameter, width of digits in byte sequences.9207// See remark below for more explanation.9208//9209// nTotalTreeHeight. Height of the XMSS/XMSS^MT tree. In a multi-tree setting,9210// it is the sum of the tree heights of each layer.9211//9212// nLayers. Number of layers. For XMSS nLayers=1, otherwise nLayers > 1. When nLayers > 1,9213// it must divide nTotalTreeHeight without remainder, so that each layer has height9214// nTotalTreeHeight/nLayers.9215//9216// cbPrefix. Number of bytes in the prefix to the hash inputs used to domain separate9217// PRF functions.9218//9219// Requirements:9220//9221// cbHashOutput must be nonzero, must be less than or equal to pHash->resultSize,9222// and must be less than or equal to SYMCRYPT_HASH_MAX_RESULT_SIZE9223//9224// nWinternitzWidth must be one of 1, 2, 4, or 89225//9226// nTotalTreeHeight must be non-zero, it must be less than or equal to 32 for9227// single-tree (nLayers = 1), and must be less than 64 for multi-tree (nLayers > 1)9228//9229// nLayers must be non-zero and must divide nTotalTreeHeight without remainder9230//9231// cbPrefix must be non-zero9232//9233// Remarks:9234//9235// RFC 8391 specifies w as the length of the Winternitz chains. Here,9236// it is used as the width of the digits in an octet string, i.e.,9237// base2 logarithm of the chain length, which is similar to its use9238// in LMS/HSS in RFC 8554.9239//924092419242#define SYMCRYPT_FLAG_XMSSKEY_VERIFY_ROOT (0x00000001)9243// Verifies the public root value when importing a private key92449245SYMCRYPT_ERROR9246SYMCRYPT_CALL9247SymCryptXmssSizeofKeyBlobFromParams(9248_In_ PCSYMCRYPT_XMSS_PARAMS pParams,9249SYMCRYPT_XMSSKEY_TYPE keyType,9250_Out_ SIZE_T* pcbKey );9251//9252// Return the size of an XMSS/XMSS^MT key blob associated with the provided XMSS parameters9253//9254//9255// Parameters:9256//9257// pParams. Pointer to an XMSS parameters structure that has been properly9258// initialized before this call.9259//9260// keyType. SYMCRYPT_XMSSKEY_TYPE_PUBLIC (resp. SYMCRYPT_XMSSKEY_TYPE_PRIVATE) to9261// retrieve the size of the public key (resp. private key) blob.9262//9263// pcbKey. Pointer to the variable to store the size of a public/private9264// key blob associated with the XMSS parameters.9265//92669267PSYMCRYPT_XMSS_KEY9268SYMCRYPT_CALL9269SymCryptXmsskeyAllocate(9270_In_ PCSYMCRYPT_XMSS_PARAMS pParams,9271UINT32 flags );9272//9273// Allocate an XMSS/XMSS^MT key object and initialize it9274//9275// After this call, the key object does not contain a key yet. It must be9276// followed by a call to SymCryptXmsskeyGenerate or SymCryptXmsskeySetValue.9277//9278// Allowed flags:9279//9280// No flags defined for this function9281//92829283SYMCRYPT_ERROR9284SYMCRYPT_CALL9285SymCryptXmsskeyGenerate(9286_Inout_ PSYMCRYPT_XMSS_KEY pKey,9287UINT32 flags );9288//9289// Generate a public/private XMSS/XMSS^MT key-pair9290//9291// Parameters:9292//9293// pKey. Key object to store the public/private key-pair9294//9295// flags. No flags defined for this function9296//9297// Return values:9298//9299// - SYMCRYPT_NO_ERROR9300// On successful key generation9301//9302// - SYMCRYPT_MEMORY_ALLOCATION_FAILURE9303// If there is not enough memory to perform key generation9304//9305// Remarks:9306//9307// - Generates a random private key (SK_XMSS, SK_PRF) and a random9308// public seed SEED, and computes the public value Root from it.9309// - If the function fails, the key object will be in an invalid state.9310//93119312SYMCRYPT_ERROR9313SYMCRYPT_CALL9314SymCryptXmsskeySetValue(9315_In_reads_bytes_( cbInput ) PCBYTE pbInput,9316SIZE_T cbInput,9317SYMCRYPT_XMSSKEY_TYPE keyType,9318UINT32 flags,9319_Inout_ PSYMCRYPT_XMSS_KEY pKey );9320//9321// Set an XMSS/XMSS^MT public/private key from key blob9322//9323// Key formats:9324//9325// PubKey: algId | Root | Seed9326// PrvKey: algId | Root | Seed | Idx | SK_XMSS | SK_PRF9327//9328// algId and Idx are 32-bit and 64-bit integers respectively, stored in big-endian format.9329// Other values are n-bytes where n is the output size (in bytes) of the hash9330// algorithm (or the truncated size if the hash output is truncated).9331//9332// Public-key format is specified in RFC 8391, whereas private-key format is not.9333// We define the private-key as an extension of the public-key with the private key9334// material.9335//9336// Parameters:9337//9338// (pbInput, cbInput). Input key blob to import the key from9339//9340// keyType. Indicates whether (pbInput, cbInput) contains a public or a private key.9341// Must be one of SYMCRYPT_XMSSKEY_TYPE_PUBLIC, or SYMCRYPT_XMSSKEY_TYPE_PRIVATE.9342//9343// flags. See below9344//9345// pKey. Pointer to the XMSS key object to be initialized from the key blob9346//9347// Allowed flags:9348//9349// - SYMCRYPT_FLAG_XMSSKEY_VERIFY_ROOT9350// Can only be specified when importing a private key. Recomputes the9351// public root value and compares it to the one that is imported from the9352// key blob.9353//9354// Return values:9355//9356// - SYMCRYPT_NO_ERROR9357// On successfully updating the key object from the provided key blob9358//9359// - SYMCRYPT_INVALID_ARGUMENT9360// If cbInput does not match a public/private key size indicated by keyType parameter9361// If an invalid flag is specified, or SYMCRYPT_FLAG_XMSSKEY_VERIFY_ROOT is9362// specified when setting a public key9363//9364// - SYMCRYPT_INVALID_BLOB9365// If the XMSS algorithm ID in the key blob does not match the algorithm ID9366// used in creating the key object pointed to by pKey9367//9368// - SYMCRYPT_MEMORY_ALLOCATION_FAILURE9369// If there is not sufficient memory for public root verification (only if9370// SYMCRYPT_FLAG_XMSSKEY_VERIFY_ROOT is set in flags)9371//9372// - SYMCRYPT_HBS_PUBLIC_ROOT_MISMATCH9373// If public root value in the key blob does not match the recomputed root value9374// (only if key blob is for a private key and SYMCRYPT_FLAG_XMSSKEY_VERIFY_ROOT is9375// specified)9376//9377// Remarks:9378//9379// - The key blob size pbInput must match the size returned by SymCryptXmssSizeofKeyBlobFromParams9380// for the same keyType and XMSS parameters the key object is created with.9381// - If the function fails, the key object will be in an invalid state.9382//93839384SYMCRYPT_ERROR9385SYMCRYPT_CALL9386SymCryptXmsskeyGetValue(9387_In_ PCSYMCRYPT_XMSS_KEY pKey,9388SYMCRYPT_XMSSKEY_TYPE keyType,9389UINT32 flags,9390_Out_writes_bytes_( cbOutput ) PBYTE pbOutput,9391SIZE_T cbOutput );9392//9393// Get public/private key value from an XMSS/XMSS^MT key object9394//9395// Key formats:9396//9397// PubKey: algId | Root | Seed9398// PrvKey: algId | Root | Seed | Idx | SK_XMSS | SK_PRF9399//9400// algId and Idx are 32-bit and 64-bit integers respectively, stored in big-endian format.9401// Other values are n-bytes where n is the output size (in bytes) of the hash9402// algorithm (or the truncated size if the hash output is truncated).9403//9404// Public-key format is specified in RFC 8391, whereas private-key format is not.9405// We define the private-key as an extension of the public-key with the private key9406// material.9407//9408// Parameters:9409//9410// pKey. The key object to export the key material from9411//9412// keyType. Type of the key (public or private) to get. If the key object9413// contains a public key, keyType must be SYMCRYPT_XMSSKEY_TYPE_PUBLIC. If9414// the key object contains a private key, keyType can be one of9415// SYMCRYPT_XMSSKEY_TYPE_PUBLIC or SYMCRYPT_XMSSKEY_TYPE_PRIVATE9416//9417// flags. No flags defined for this function9418//9419// (pbOutput, cbOutput). Buffer to store the exported key blob. cbOutput must match9420// the size of the key to be exported, which can be queried by calling9421// SymCryptXmssSizeofKeyBlobFromParams.9422//9423// Return values:9424//9425// - SYMCRYPT_NO_ERROR9426// On successful exporting of the key9427//9428// - SYMCRYPT_INVALID_ARGUMENT9429// If cbOutput does not match the exact size of the key blob for the specified9430// keyType9431// If the key object does not contain private key material when keyType9432// equals SYMCRYPT_XMSSKEY_TYPE_PRIVATE9433// If unsupported flags are specified in flags parameter9434//94359436VOID9437SYMCRYPT_CALL9438SymCryptXmsskeyFree(9439_Inout_ PSYMCRYPT_XMSS_KEY pKey);9440//9441// Free an allocated XMSS/XMSS^MT key object9442//94439444SIZE_T9445SYMCRYPT_CALL9446SymCryptXmssSizeofSignatureFromParams(9447_In_ PCSYMCRYPT_XMSS_PARAMS pParams );9448//9449// Return the size of the signature for given XMSS parameters9450//94519452SYMCRYPT_ERROR9453SYMCRYPT_CALL9454SymCryptXmssSign(9455_Inout_ PSYMCRYPT_XMSS_KEY pKey,9456_In_reads_bytes_( cbMessage ) PCBYTE pbMessage,9457SIZE_T cbMessage,9458UINT32 flags,9459_Out_writes_bytes_( cbSignature ) PBYTE pbSignature,9460SIZE_T cbSignature );9461//9462// Sign a message using XMSS/XMSS^MT9463//9464// Parameters:9465//9466// pKey. Private XMSS/XMSS^MT key used in signing9467//9468// (pbMessage, cbMessage). Message to be signed9469//9470// flags. No flags defined for this function9471//9472// (pbSignature, cbSignature). Buffer to store the generated signature9473//9474// Requirements:9475//9476// pKey must contain the private key9477//9478// cbSignature must be equal to the generated signature size9479//9480// Return values:9481//9482// - SYMCRYPT_NO_ERROR on successful signature generation9483//9484// - SYMCRYPT_INVALID_ARGUMENT9485// If flags parameter is invalid,9486// or if the key object does not contain private key,9487// or cbSignature is not of correct size9488//9489// - SYMCRYPT_HBS_NO_OTS_KEYS_LEFT9490// If the key doesn't have any one-time-signatures left for signing9491//9492// Remarks:9493//9494// The input pbMessage can be of arbitrary length and its randomized hash will be the actual9495// value that is going to be signed with a WOTSP signature. Applications wanting to pass the hash9496// value of a message to be signed as opposed to the message itself must make sure to have9497// domain separation between the space of messages and the hashes of the messages.9498//9499// The signature size can be queried with SymCryptSizeofXmssSignatureFromParams function.9500//950195029503SYMCRYPT_ERROR9504SYMCRYPT_CALL9505SymCryptXmssVerify(9506_Inout_ PSYMCRYPT_XMSS_KEY pKey,9507_In_reads_bytes_( cbMessage ) PCBYTE pbMessage,9508SIZE_T cbMessage,9509UINT32 flags,9510_In_reads_bytes_( cbSignature ) PCBYTE pbSignature,9511SIZE_T cbSignature );9512//9513// Verify an XMSS/XMSS^MT signature on a message9514//9515// Parameters:9516//9517// pKey. XMSS key used to verify the signature9518//9519// (pbMessage, cbMessage) Message for which the signature was created9520//9521// flags. No flags defined for this function9522//9523// (pbSignature, cbSignature) XMSS or XMSS^MT signature9524//9525// Return values:9526//9527// - SYMCRYPT_NO_ERROR9528// If signature verification succeeds9529//9530// - SYMCRYPT_INVALID_ARGUMENT9531// If flags is invalid or cbSignature is of incorrect size9532//9533// - SYMCRYPT_SIGNATURE_VERIFICATION_ERROR9534// If the signature is not valid9535//9536// Requirements:9537//9538// cbSignature must be equal to the exact signature size associated with9539// the XMSS parameters.9540//9541// Remarks:9542//9543// In XMSS, the message can be arbitrarily long and a randomized hash of the message9544// will be computed first to be signed by the WOTSP internally.9545//95469547VOID9548SYMCRYPT_CALL9549SymCryptXmssSelftest(void);9550//9551// FIPS self-test for signature verification9552//95539554//========================================================================9555// Leighton-Micali Hash-Based Signatures (LMS) - LMS external struct definitions - implementing9556// RFC8554/NIST Special Publication 800-2089557//9558typedef enum _SYMCRYPT_LMS_ALGID9559{9560//9561// Algorithm IDs for Leighton-Micali Hash-Based Signatures (LMS)9562// M equals the output length of the hash function, where H is the tree height.9563// The M parameter primarily affects the security and size of the signatures, while the H parameter9564// impacts the number of possible signatures and the computational cost for signing and verification.9565// Larger M increases security and signature size, but increases the computational cost9566// Higher H means more signatures but higher computational cost for signing and verification9567//9568SYMCRYPT_LMS_SHA256_M32_H5 = 0x00000005,9569SYMCRYPT_LMS_SHA256_M32_H10 = 0x00000006,9570SYMCRYPT_LMS_SHA256_M32_H15 = 0x00000007,9571SYMCRYPT_LMS_SHA256_M32_H20 = 0x00000008,9572SYMCRYPT_LMS_SHA256_M32_H25 = 0x00000009,9573SYMCRYPT_LMS_SHA256_M24_H5 = 0x0000000A,9574SYMCRYPT_LMS_SHA256_M24_H10 = 0x0000000B,9575SYMCRYPT_LMS_SHA256_M24_H15 = 0x0000000C,9576SYMCRYPT_LMS_SHA256_M24_H20 = 0x0000000D,9577SYMCRYPT_LMS_SHA256_M24_H25 = 0x0000000E,9578SYMCRYPT_LMS_SHAKE_M32_H5 = 0x0000000F,9579SYMCRYPT_LMS_SHAKE_M32_H10 = 0x00000010,9580SYMCRYPT_LMS_SHAKE_M32_H15 = 0x00000011,9581SYMCRYPT_LMS_SHAKE_M32_H20 = 0x00000012,9582SYMCRYPT_LMS_SHAKE_M32_H25 = 0x00000013,9583SYMCRYPT_LMS_SHAKE_M24_H5 = 0x00000014,9584SYMCRYPT_LMS_SHAKE_M24_H10 = 0x00000015,9585SYMCRYPT_LMS_SHAKE_M24_H15 = 0x00000016,9586SYMCRYPT_LMS_SHAKE_M24_H20 = 0x00000017,9587SYMCRYPT_LMS_SHAKE_M24_H25 = 0x00000018,9588} SYMCRYPT_LMS_ALGID;95899590typedef enum _SYMCRYPT_LMS_OTS_ALGID9591{9592// Algorithm IDs for Leighton-Micali Hash-Based Signatures (LMS) One-Time-Signature (OTS)9593// N parameter represents the number of bytes in the hash function output. It determines the size of the hash values used in9594// the LMS OTS scheme.9595// W parameter represents the width of the Winternitz parameter used in LMS OTS. A larger value of w results in shorter9596// signatures but requires more computation during key generation, signature generation, and signature verification.9597//9598SYMCRYPT_LMS_OTS_SHA256_N32_W1 = 0x00000001,9599SYMCRYPT_LMS_OTS_SHA256_N32_W2 = 0x00000002,9600SYMCRYPT_LMS_OTS_SHA256_N32_W4 = 0x00000003,9601SYMCRYPT_LMS_OTS_SHA256_N32_W8 = 0x00000004,9602SYMCRYPT_LMS_OTS_SHA256_N24_W1 = 0x00000005,9603SYMCRYPT_LMS_OTS_SHA256_N24_W2 = 0x00000006,9604SYMCRYPT_LMS_OTS_SHA256_N24_W4 = 0x00000007,9605SYMCRYPT_LMS_OTS_SHA256_N24_W8 = 0x00000008,9606SYMCRYPT_LMS_OTS_SHAKE_N32_W1 = 0x00000009,9607SYMCRYPT_LMS_OTS_SHAKE_N32_W2 = 0x0000000A,9608SYMCRYPT_LMS_OTS_SHAKE_N32_W4 = 0x0000000B,9609SYMCRYPT_LMS_OTS_SHAKE_N32_W8 = 0x0000000C,9610SYMCRYPT_LMS_OTS_SHAKE_N24_W1 = 0x0000000D,9611SYMCRYPT_LMS_OTS_SHAKE_N24_W2 = 0x0000000E,9612SYMCRYPT_LMS_OTS_SHAKE_N24_W4 = 0x0000000F,9613SYMCRYPT_LMS_OTS_SHAKE_N24_W8 = 0x00000010,9614} SYMCRYPT_LMS_OTS_ALGID;96159616// Verifies the public key root value when importing a private key9617#define SYMCRYPT_FLAG_LMSKEY_VERIFY_ROOT (0x00000001)96189619typedef enum _SYMCRYPT_LMSKEY_TYPE9620{9621SYMCRYPT_LMSKEY_TYPE_NONE = 0, // Key object does not contain any key material9622SYMCRYPT_LMSKEY_TYPE_PUBLIC = 1, // Key object contains only public key9623SYMCRYPT_LMSKEY_TYPE_PRIVATE = 2, // Key object contains both public key and private key9624} SYMCRYPT_LMSKEY_TYPE;9625// The format of the private key blob is as follows:9626// [ Public key parts || Private key parts ]9627// [ 4 || 4 || 16 || m || 4 || m ]9628// [ LmsAlgId || LmsOtsAlgId || I || RootNode || NextUnusedLeaf || Seed ]9629//9630// The format of the public key blob is as follows:9631// [ 4 || 4 || 16 || m ]9632// [ LmsAlgId || LmsOtsAlgId || I || RootNode ]96339634//=====================================================9635// LMS operations96369637SYMCRYPT_ERROR9638SYMCRYPT_CALL9639SymCryptLmsParamsFromAlgId(9640SYMCRYPT_LMS_ALGID lmsAlgID,9641SYMCRYPT_LMS_OTS_ALGID lmsOtsAlgID,9642_Out_ PSYMCRYPT_LMS_PARAMS pParams);9643//9644// This function populates a SYMCRYPT_LMS_PARAMS structure with the predefined parameter sets for a given LMS9645// algorithm identifier and LMS OTS algorithm identifier. The resulting structure can be used to create LMS key objects.9646// The values defined by SYMCRYPT_LMS_OTS_ALGID and SYMCRYPT_LMS_ALGID are all of the NIST SP 800-208 parameter9647// sets supported by SymCrypt.9648//9649// Parameters:9650// lmsAlgID: The LMS algorithm identifier to use9651//9652// lmsOtsAlgID: The LMS OTS algorithm identifier to use9653//9654// pParams: A pointer to a SYMCRYPT_LMS_PARAMS structure that will be populated with the predefined parameter sets9655//9656// Return value:9657// If the function succeeds, it returns SYMCRYPT_NO_ERROR9658// If the function fails, it returns SYMCRYPT_INVALID_ARGUMENT9659//96609661SYMCRYPT_ERROR9662SYMCRYPT_CALL9663SymCryptLmsSetParams(9664_Out_ PSYMCRYPT_LMS_PARAMS pParams,9665UINT32 lmsAlgID,9666UINT32 lmsOtsAlgID,9667_In_ PCSYMCRYPT_HASH pLmsHashFunction,9668UINT32 cbHashOutput,9669UINT32 nTreeHeight,9670UINT32 nWinternitzChainWidth);9671//9672// This function allows for the customization of non-standard parameter sets, which cannot be set using LmsParamsFromAlgId.9673//9674// Parameters:9675// pParams: A pointer to a SYMCRYPT_LMS_PARAMS structure to be initialized.9676//9677// lmsAlgID: LMS algorithm identifier, will be embedded in key and signature objects.9678//9679// lmsOtsAlgID: LMS OTS algorithm identifier, will be embedded in key and signature objects.9680//9681// pLmsHashFunction: A pointer to the hash function to be used for the LMS system.9682//9683// cbHashOutput: The number of bytes for each tree node, equal to the output length of the hash function.9684// Must be less than or equal to 32.9685//9686// nTreeHeight: The height of the LMS tree. Must be < 32, there are (2^nTreeHeight) leaves in the tree.9687//9688// nWinternitzChainWidth: An integer that specifies the base2 logarithm of Winternitz chain lengths.9689// Must be one of 1, 2, 4, or 89690//9691// Return value:9692// If the function succeeds, it fills PSYMCRYPT_LMS_PARAMS structure by user defined values and return SYMCRYPT_NO_ERROR.9693// Otherwise, it sets the values of PSYMCRYPT_LMS_PARAMS to 0 and returns SYMCRYPT_INVALID_ARGUMENT.9694//96959696SYMCRYPT_ERROR9697SYMCRYPT_CALL9698SymCryptLmsSizeofKeyBlobFromParams(9699_In_ PCSYMCRYPT_LMS_PARAMS pParams,9700SYMCRYPT_LMSKEY_TYPE keyType,9701_Out_ SIZE_T* pcbKey);9702//9703// Returns the size of an LMS key blob based on the provided LMS parameters and keyType.9704//9705// Parameters:9706// pParams: A pointer to a SYMCRYPT_LMS_PARAMS structure that specifies the parameters of the LMS key.9707//9708// keyType: Specifies the type of blob for which to retrieve the size.9709// Must be one of SYMCRYPT_LMSKEY_TYPE_PUBLIC or SYMCRYPT_LMSKEY_TYPE_PRIVATE.9710//9711// pcbKey: Pointer to the variable to store the size of a public/private9712// key blob associated with the LMS parameters.9713//9714// Return value:9715// If the function succeeds, it returns SYMCRYPT_NO_ERROR. In case keyType is not recognized9716// it returns SYMCRYPT_INVALID_ARGUMENT.9717//97189719PSYMCRYPT_LMS_KEY9720SYMCRYPT_CALL9721SymCryptLmskeyAllocate(9722_In_ PCSYMCRYPT_LMS_PARAMS pParams,9723UINT32 flags);9724//9725// This function allocates a new SYMCRYPT_LMS_KEY object, which represents a key for the Leighton-Micali Signature (LMS)9726// scheme, based on the given PCSYMCRYPT_LMS_PARAMS. The function allocates memory for the key object, and returns a pointer to it.9727// The caller is responsible for freeing the memory when the key is no longer needed, using the SymCryptLmskeyFree function.9728//9729// Parameters:9730// pParams: A pointer to a constant SYMCRYPT_LMS_PARAMS structure that describes9731// the LMS parameters to be used for the key.9732// The structure must be non-null, and must be initialized by one of the initialization functions:9733// SymCryptLmsParamsFromAlgId or SymCryptLmsSetParams.9734//9735// flags: Currently not used. Must be set to 0.9736//9737// Return value:9738// If the function succeeds, it returns a pointer to the newly created SYMCRYPT_LMS_KEY object.9739// Otherwise, it returns NULL, indicating an error that should be handled by the caller.9740//97419742SYMCRYPT_ERROR9743SYMCRYPT_CALL9744SymCryptLmskeyGenerate(9745_Inout_ PSYMCRYPT_LMS_KEY pKey,9746UINT32 flags);9747//9748// This function generates an LMS public/private key pair in the pKey object.9749//9750// Parameters:9751// pKey: A pointer to a SYMCRYPT_LMS_KEY structure that represents the LMS key object to be initialized. The structure9752// must be valid and non-null, and must have been previously created using the SymCryptLmskeyAllocate9753// function. If the key object already contains key values, they will be overwritten by the generated values.9754//9755// flags: Currently not used. Must be set to 0.9756//9757// Return value:9758// If the function succeeds, it returns SYMCRYPT_NO_ERROR. Otherwise, it returns an error code that describes the nature of the9759// failure, such as SYMCRYPT_INVALID_ARGUMENT.9760//97619762SYMCRYPT_ERROR9763SYMCRYPT_CALL9764SymCryptLmskeySetValue(9765_In_reads_bytes_(cbInput) PCBYTE pbInput,9766SIZE_T cbInput,9767SYMCRYPT_LMSKEY_TYPE keyType,9768UINT32 flags,9769_Inout_ PSYMCRYPT_LMS_KEY pKey);9770//9771// This function imports an LMS key from a buffer, setting the key object with the provided data.9772//9773// Parameters:9774// pbInput: A pointer to a byte buffer containing the key data to be imported into the LMS key object9775// The format of the input buffer is specified by the SYMCRYPT_LMSKEY_TYPE enumeration.9776//9777// cbInput: The size, in bytes, of the key data buffer pointed to by pbInput9778//9779// keyType: Indicates whether (pbInput, cbInput) contains a public or a private key.9780// Must be one of SYMCRYPT_LMSKEY_TYPE_PUBLIC, or SYMCRYPT_LMSKEY_TYPE_PRIVATE.9781//9782// flags: See allowed flags below.9783//9784// pKey: A pointer to a SYMCRYPT_LMS_KEY structure that will receive the imported key from the buffer pbInput9785//9786// Allowed flags:9787// SYMCRYPT_FLAG_LMSKEY_VERIFY_ROOT: Can only be specified when importing a private key. Recomputes the9788// public root value and compares it to the one that is imported from the key blob.9789//9790// Return value:9791// If the function succeeds, it returns SYMCRYPT_NO_ERROR and the SYMCRYPT_LMS_KEY structure is set with the imported key data.9792// If the function fails, it returns an error code that describes the nature of the failure, such as SYMCRYPT_INVALID_ARGUMENT.9793//97949795SYMCRYPT_ERROR9796SYMCRYPT_CALL9797SymCryptLmskeyGetValue(9798_In_ PCSYMCRYPT_LMS_KEY pKey,9799SYMCRYPT_LMSKEY_TYPE keyType,9800UINT32 flags,9801_Out_writes_bytes_(cbOutput) PBYTE pbOutput,9802SIZE_T cbOutput);9803//9804// This function retrieves the public or private key value from an LMS key object, depending on the keyType parameter9805//9806// Parameters:9807// pKey: A pointer to a SYMCRYPT_LMS_KEY structure that represents the LMS key object to retrieve the key value from.9808// The structure must be valid and non-null, and must contain the key values to retrieve9809//9810// keyType: Type of the key (public or private) to get. If the key object only9811// contains a public key, keyType must be SYMCRYPT_LMSKEY_TYPE_PUBLIC. If9812// the key object contains a private key, keyType can be one of9813// SYMCRYPT_LMSKEY_TYPE_PUBLIC or SYMCRYPT_LMSKEY_TYPE_PRIVATE9814//9815// flags: Currently not used. Must be set to 0.9816//9817// pbOutput: A buffer to hold the key value. The buffer must be large enough to hold the key value.9818// The format of the output buffer is specified by the SYMCRYPT_LMSKEY_TYPE enumeration.9819//9820// cbOutput: The size of the pbOutput buffer in bytes9821//9822// Return value:9823// If the function succeeds, it returns SYMCRYPT_NO_ERROR. Otherwise, it returns SYMCRYPT_INVALID_ARGUMENT.9824//98259826VOID9827SYMCRYPT_CALL9828SymCryptLmskeyFree(9829_Inout_ PSYMCRYPT_LMS_KEY pKey);9830//9831// This function frees the memory that was allocated for the given LMS key object, which was previously created using the9832// SymCryptLmskeyAllocate function. The function wipes and deallocates the memory.9833//9834// Parameters:9835// pKey: A pointer to a SYMCRYPT_LMS_KEY structure that represents the LMS key object to be freed. The structure9836// must be valid and non-null, and must have been previously created using the SymCryptLmskeyAllocate function.9837//9838// Return value:9839// The function does not return a value.9840//98419842SIZE_T9843SYMCRYPT_CALL9844SymCryptLmsSizeofSignatureFromParams(9845_In_ PCSYMCRYPT_LMS_PARAMS pParams);9846//9847// This function returns the size, in bytes, of the signature that will be generated by the LMS signature scheme, based on the9848// specified LMS parameters.9849//9850// Parameters:9851// pParams: A pointer to a SYMCRYPT_LMS_PARAMS structure that represents the parameters associated with the LMS key to9852// use for computing the signature size. The structure must be valid and non-null.9853//9854// Return value:9855// Signature size in bytes.9856//98579858SYMCRYPT_ERROR9859SYMCRYPT_CALL9860SymCryptLmsSign(9861_Inout_ PSYMCRYPT_LMS_KEY pKey,9862_In_reads_bytes_(cbMessage) PCBYTE pbMessage,9863SIZE_T cbMessage,9864UINT32 flags,9865_Out_writes_bytes_(cbSignature) PBYTE pbSignature,9866SIZE_T cbSignature);9867//9868// This function generates an LMS signature for the given message, using the private key in the given LMS key object.9869// The function fills the buffer pointed to by pbSignature with the LMS signature. It uses the LMS parameters9870// and key values that were specified when the key object was created to generate the signature.9871// Stateful hash-based signatures are not approved by FIPS for key generation and signature generation in software9872// modules. Special care must be taken to ensure that the same private key state is not used more than once to9873// sign messages. This can be done, for instance, by releasing a signature only after verifying that the private9874// key has been updated and serialized to a physical storage.9875//9876// Parameters:9877// pKey: A pointer to a SYMCRYPT_LMS_KEY structure that represents the LMS key object to be used for signing the message.9878// The structure must be valid and non-null, and must contain the private key values for the LMS scheme. The private key9879// must have been initialized previously using the SymCryptLmsKeyGenerate or SymCryptLmskeySetValue function.9880//9881// pbMessage: A pointer to a buffer that contains the message to be signed.9882//9883// cbMessage: The length in bytes of the message to be signed.9884//9885// flags: Currently not used. Must be set to 0.9886//9887// pbSignature: A pointer to the buffer that receives the computed signature. It must be large enough to hold the9888// generated signature. The required size can be retrieved using: SymCryptLmsSizeofSignatureFromParams.9889//9890// cbSignature: The size of the signature buffer pbSignature. If the passed size is different than the9891// required signature size an error will be returned.9892//9893// Return value:9894// SYMCRYPT_NO_ERROR - If the function succeeds9895//9896// SYMCRYPT_HBS_NO_OTS_KEYS_LEFT - If the key has run out of available OTS keys9897//9898// SYMCRYPT_INVALID_ARGUMENT - If one of the input parameters is invalid9899//9900// Remarks:9901// The LMS signing process inherits its signature from the LMS OTS, which means that it will always compute a digest of the9902// given message before signing, even if a hash value is provided as the message.9903// Developers should always be consistent with the input to the LMS sign and verify functions and ensure that the input message9904// is in the correct format before passing it to these functions9905//99069907SYMCRYPT_ERROR9908SYMCRYPT_CALL9909SymCryptLmsVerify(9910_In_ PCSYMCRYPT_LMS_KEY pKey,9911_In_reads_bytes_(cbMessage) PCBYTE pbMessage,9912SIZE_T cbMessage,9913UINT32 flags,9914_In_reads_bytes_(cbSignature) PCBYTE pbSignature,9915SIZE_T cbSignature);9916//9917// This function verifies the given LMS signature (pbSignature) for the given message (pbMessage), using the public key9918// in the given LMS key object. The function returns SYMCRYPT_NO_ERROR if the signature is valid, and an error code otherwise.9919//9920// Parameters:9921// pKey: A pointer to a SYMCRYPT_LMS_KEY structure that represents the LMS key object to be used for verifying9922// the signature. The structure must be valid and non-null, and must contain the public or private key values for the LMS scheme.9923// The public key must have been generated previously using the SymCryptLmsKeyGenerate or SymCryptLmskeySetValue functions, and must match the9924// private key that was used to generate the signature.9925//9926// pbMessage: A pointer to a buffer that contains the message that was signed.The buffer must be valid and non-null, and9927// must contain at least cbMessage bytes of data.9928//9929// cbMessage: The length in bytes of the message that was signed. The length should be set to the actual size of the message.9930// If the message is larger than the maximum size allowed by the LMS parameters, the function will return an error.9931//9932// flags: Currently not used. Must be set to 0.9933//9934// pbSignature: A pointer to a buffer that contains the signature that was generated for the message. The buffer must9935// be valid and non-null, and must contain at least cbSignature bytes.9936//9937// cbSignature: The length in bytes of the signature buffer that contains the signature. The length must be9938// equal to the exact signature size associated with the given LMS parameters and key values.9939//9940// Return value:9941// SYMCRYPT_NO_ERROR - If the function succeeds9942//9943// SYMCRYPT_INVALID_ARGUMENT - If the signature structure is not correct or if there is a mismatch between the9944// input parameters.9945//9946// SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE - If the signature verification fails9947//99489949VOID9950SYMCRYPT_CALL9951SymCryptLmsSelftest(void);995299539954// MLKEMKEY objects' API9955//99569957// MLKEM key formats9958// ==================9959// The below formats apply **only to external formats**: When somebody is importing or exporting9960// a key. The internal format of the keys is not visible to the caller.9961typedef enum _SYMCRYPT_MLKEMKEY_FORMAT {9962SYMCRYPT_MLKEMKEY_FORMAT_NULL = 0,9963SYMCRYPT_MLKEMKEY_FORMAT_PRIVATE_SEED = 1,9964// 64-byte concatenation of d || z from FIPS 203. Smallest representation of a full9965// ML-KEM key.9966// On its own it is ambiguous which ML-KEM parameter set this represents; callers wanting to9967// store this format must track the parameter set alongside the key.9968SYMCRYPT_MLKEMKEY_FORMAT_DECAPSULATION_KEY = 2,9969// Standard byte encoding of an ML-KEM Decapsulation key, per FIPS 203.9970// Size is 1632, 2400, or 3168 bytes for ML-KEM 512, 768, and 1024 respectively.9971SYMCRYPT_MLKEMKEY_FORMAT_ENCAPSULATION_KEY = 3,9972// Standard byte encoding of an ML-KEM Encapsulation key, per FIPS 203.9973// Size is 800, 1184, or 1568 bytes for ML-KEM 512, 768, and 1024 respectively.9974} SYMCRYPT_MLKEMKEY_FORMAT;997599769977typedef enum _SYMCRYPT_MLKEM_PARAMS {9978SYMCRYPT_MLKEM_PARAMS_NULL = 0,9979SYMCRYPT_MLKEM_PARAMS_MLKEM512 = 1,9980SYMCRYPT_MLKEM_PARAMS_MLKEM768 = 2,9981SYMCRYPT_MLKEM_PARAMS_MLKEM1024 = 3,9982} SYMCRYPT_MLKEM_PARAMS;9983//9984// Currently supported ML-KEM parameter sets are represented externally only by the enum9985//99869987PSYMCRYPT_MLKEMKEY9988SYMCRYPT_CALL9989SymCryptMlKemkeyAllocate(9990SYMCRYPT_MLKEM_PARAMS params );9991//9992// Allocate and create a new MLKEMKEY object sized according to the specified parameters.9993//9994// This call does not initialize the key. It should be9995// followed by a call to SymCryptMlKemkeyGenerate or9996// SymCryptMlKemkeySetValue.9997//99989999VOID10000SYMCRYPT_CALL10001SymCryptMlKemkeyFree(10002_Inout_ PSYMCRYPT_MLKEMKEY pkMlKemkey );100031000410005// d and z are each 32 bytes10006#define SYMCRYPT_MLKEM_PRIVATE_SEED_SIZE (2*32)1000710008#define SYMCRYPT_MLKEM_ENCAPSULATION_KEY_SIZE_MLKEM512 (800)10009#define SYMCRYPT_MLKEM_ENCAPSULATION_KEY_SIZE_MLKEM768 (1184)10010#define SYMCRYPT_MLKEM_ENCAPSULATION_KEY_SIZE_MLKEM1024 (1568)1001110012#define SYMCRYPT_MLKEM_DECAPSULATION_KEY_SIZE_MLKEM512 (1632)10013#define SYMCRYPT_MLKEM_DECAPSULATION_KEY_SIZE_MLKEM768 (2400)10014#define SYMCRYPT_MLKEM_DECAPSULATION_KEY_SIZE_MLKEM1024 (3168)1001510016SYMCRYPT_ERROR10017SYMCRYPT_CALL10018SymCryptMlKemSizeofKeyFormatFromParams(10019SYMCRYPT_MLKEM_PARAMS params,10020SYMCRYPT_MLKEMKEY_FORMAT mlKemkeyformat,10021_Out_ SIZE_T* pcbKeyFormat );10022//10023// Gives the size in bytes of the blob of the given format for the given ML-KEM10024// parameters via pcbKeyFormat output.10025// Returns SYMCRYPT_INCOMPATIBLE_FORMAT if mlKemkeyFormat is an unsupported value,10026// or SYMCRYPT_INVALID_ARGUMENT if other parameters are invalid.10027//1002810029#define SYMCRYPT_MLKEM_CIPHERTEXT_SIZE_MLKEM512 (768)10030#define SYMCRYPT_MLKEM_CIPHERTEXT_SIZE_MLKEM768 (1088)10031#define SYMCRYPT_MLKEM_CIPHERTEXT_SIZE_MLKEM1024 (1568)1003210033SYMCRYPT_ERROR10034SYMCRYPT_CALL10035SymCryptMlKemSizeofCiphertextFromParams(10036SYMCRYPT_MLKEM_PARAMS params,10037_Out_ SIZE_T* pcbCiphertext );10038//10039// Gives the size in bytes of the ciphertext for the given ML-KEM parameters.10040// Returns SYMCRYPT_INVALID_ARGUMENT if parameters are invalid.10041//1004210043SYMCRYPT_ERROR10044SYMCRYPT_CALL10045SymCryptMlKemkeyGenerate(10046_Inout_ PSYMCRYPT_MLKEMKEY pkMlKemkey,10047UINT32 flags );10048//10049// Generate a new random ML-KEM key using the information from the10050// parameters passed to SymCryptMlKemkeyAllocate.10051//10052// Allowed flags:10053//10054// - SYMCRYPT_FLAG_KEY_NO_FIPS10055// Opt-out of performing validation required for FIPS10056//10057// Described in more detail in the "Flags for asymmetric key generation and import" section above10058//1005910060SYMCRYPT_ERROR10061SYMCRYPT_CALL10062SymCryptMlKemkeySetValue(10063_In_reads_bytes_( cbSrc ) PCBYTE pbSrc,10064SIZE_T cbSrc,10065SYMCRYPT_MLKEMKEY_FORMAT mlKemkeyFormat,10066UINT32 flags,10067_Inout_ PSYMCRYPT_MLKEMKEY pkMlKemkey );10068//10069// Import key material to an ML-KEM key object. The arguments are the following:10070// - (pbSrc, cbSrc): a buffer containing a representation of an ML-KEM key,10071// in format specified by mlKemkeyFormat.10072// - mlKemkeyFormat format of the input10073//10074// Allowed flags:10075//10076// - SYMCRYPT_FLAG_KEY_NO_FIPS10077// Opt-out of performing validation required for FIPS10078//10079// - SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION10080// Opt-out of performing almost all validation - must be specified with SYMCRYPT_FLAG_KEY_NO_FIPS10081//10082// Remarks:10083// - cbSrc must be equal to the cbKeyFormat returned from10084// SymCryptMlKemSizeofKeyFormatFromParams(params, mlKemkeyFormat, &cbKeyFormat), though typically this10085// value can be known statically (see definition of SYMCRYPT_MLKEMKEY_FORMAT)10086//1008710088SYMCRYPT_ERROR10089SYMCRYPT_CALL10090SymCryptMlKemkeyGetValue(10091_In_ PCSYMCRYPT_MLKEMKEY pkMlKemkey,10092_Out_writes_bytes_( cbDst ) PBYTE pbDst,10093SIZE_T cbDst,10094SYMCRYPT_MLKEMKEY_FORMAT mlKemkeyFormat,10095UINT32 flags );10096//10097// Export key material from an ML-KEM key object. The arguments are the following:10098// - (pbDst, cbDst): a buffer into which a representation of an ML-KEM key is10099// written, in the format specified by mlKemkeyFormat.10100// - mlKemkeyFormat format of the output10101//10102// Allowed flags:10103// - None.10104//10105// Remarks:10106// - If the key object does not have the information required to export to the format10107// specified by mlKemkeyFormat this function will return SYMCRYPT_INCOMPATIBLE_FORMAT.10108// - cbDst must be equal to the cbKeyFormat returned from10109// SymCryptMlKemSizeofKeyFormatFromParams(params, mlKemkeyFormat, &cbKeyFormat), though typically this10110// value can be known statically (see definition of SYMCRYPT_MLKEMKEY_FORMAT)10111//1011210113SYMCRYPT_ERROR10114SYMCRYPT_CALL10115SymCryptMlKemEncapsulate(10116_In_ PCSYMCRYPT_MLKEMKEY pkMlKemkey,10117_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,10118SIZE_T cbAgreedSecret,10119_Out_writes_bytes_( cbCiphertext ) PBYTE pbCiphertext,10120SIZE_T cbCiphertext );10121//10122// Performs the Encapsulate operation of ML-KEM.10123// This uses the public information of an ML-KEM keypair to generate an agreed secret10124// and a ciphertext. Only a peer with the private information of an ML-KEM keypair can10125// decapsulate the ciphertext to compute the agreed secret.10126//10127// The arguments are the following:10128// - pkMlKemkey: a key which contains public information required for encapsulation.10129// - (pbAgreedSecret, cbAgreedSecret): a buffer into which the generated secret is written.10130// Currently cbAgreedSecret must be 32 for all parameterizations of ML-KEM.10131// - (pbCiphertext, cbCiphertext): a buffer into which the encapsulated secret is written.10132// cbCiphertext must equal cbCiphertext given by SymCryptMlKemSizeofCiphertextFromParams,10133// though typically this value can be known statically (see definition of10134// SYMCRYPT_MLKEM_CIPHERTEXT_SIZE_*).10135//1013610137SYMCRYPT_ERROR10138SYMCRYPT_CALL10139SymCryptMlKemDecapsulate(10140_In_ PCSYMCRYPT_MLKEMKEY pkMlKemkey,10141_In_reads_bytes_( cbCiphertext ) PCBYTE pbCiphertext,10142SIZE_T cbCiphertext,10143_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,10144SIZE_T cbAgreedSecret );10145//10146// Performs the Decapsulate operation of ML-KEM.10147// This uses the private information of an ML-KEM keypair to generate an agreed10148// secret from a ciphertext.10149//10150// The arguments are the following:10151// - pkMlKemkey: a key which contains private information required for decapsulation.10152// - (pbCiphertext, cbCiphertext): a buffer containing an encapsulated secret.10153// cbCiphertext must equal cbCiphertext given by SymCryptMlKemSizeofCiphertextFromParams,10154// though typically this value can be known statically (see definition of10155// SYMCRYPT_MLKEM_CIPHERTEXT_SIZE_*).10156// - (pbAgreedSecret, cbAgreedSecret): a buffer into which the generated secret is written.10157// Currently cbAgreedSecret must be 32 for all parameterizations of ML-KEM.10158//10159// Note: Given an invalid, but correctly-sized, ciphertext, the ML-KEM Decapsulation operation10160// will "implicitly reject" the ciphertext, by returning success in equal time to a valid10161// decapsulation operation, with pseudo-random agreed secret output. This forces higher10162// level protocols to fail later when symmetric keys of peers do not match.10163// So decapsulate will only ever return an error if there are programming errors (e.g. incorrect size),10164// or something fundamentally goes wrong with the environment (e.g. internal memory allocation fails).10165//1016610167VOID10168SYMCRYPT_CALL10169SymCryptMlKemSelftest(void);10170//10171// FIPS self-test for ML-KEM. If the self-test fails, SymCryptFatal will be called to fastfail.10172// The self-test will automatically be performed before first operational use of ML-KEM if using10173// keys with FIPS validation, so most callers should never use this function.10174//1017510176//10177// COMPOSITE MLKEMKEY objects' API10178//10179// The below formats apply **only to external formats**: When somebody is importing or exporting10180// a key. The internal format of the keys is not visible to the caller.10181typedef enum _SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT {10182SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT_NULL = 0,10183SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT_IRTF_PRIVATE_SEED = 1,10184// 32-byte seed for deriving Composite ML-KEM key, per irtf-cfrg-hybrid-kems CG framework10185SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT_LAMPS_PRIVATE_KEY = 2,10186// Standard byte encoding of a Composite ML-KEM private key, per LAMPS composite ML-KEM draft 12.10187// Concatenation of ML-KEM private seed and private key of the traditional component:10188// mlkemSeed || tradSK10189// Size in bytes are MLKEM768_P256: 115, MLKEM768_X25519: 96, MLKEM1024_P384: 12810190SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT_PUBLIC_KEY = 3,10191// Standard byte encoding of a Composite ML-KEM public key, per irtf-cfrg-hybrid-kems CG framework10192// and LAMPS composite ML-KEM draft 12.10193// Concatenation of ML-KEM encapsulation key and public key of the traditional component:10194// mlkemPK || tradPK10195// Size in bytes are MLKEM768_P256: 1249, MLKEM768_X25519: 1216, MLKEM1024_P384: 166510196} SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT;101971019810199typedef enum _SYMCRYPT_COMPOSITE_MLKEM_PARAMS {10200SYMCRYPT_COMPOSITE_MLKEM_PARAMS_NULL = 0,10201SYMCRYPT_COMPOSITE_MLKEM_PARAMS_MLKEM768_P256 = 1,10202SYMCRYPT_COMPOSITE_MLKEM_PARAMS_MLKEM768_X25519 = 2,10203SYMCRYPT_COMPOSITE_MLKEM_PARAMS_MLKEM1024_P384 = 3,10204} SYMCRYPT_COMPOSITE_MLKEM_PARAMS;10205//10206// Currently supported Composite ML-KEM parameter sets are represented externally only by the enum10207//1020810209PSYMCRYPT_COMPOSITE_MLKEMKEY10210SYMCRYPT_CALL10211SymCryptCompositeMlKemkeyAllocate(10212SYMCRYPT_COMPOSITE_MLKEM_PARAMS params );10213//10214// Allocate and create a new COMPOSITE_MLKEMKEY object sized according to the specified parameters.10215//10216// This call does not initialize the key. It should be10217// followed by a call to SymCryptCompositeMlKemkeyGenerate or10218// SymCryptCompositeMlKemkeySetValue.10219//1022010221VOID10222SYMCRYPT_CALL10223SymCryptCompositeMlKemkeyFree(10224_Inout_ PSYMCRYPT_COMPOSITE_MLKEMKEY pkCompositeMlKemkey );102251022610227#define SYMCRYPT_COMPOSITE_MLKEM_IRTF_PRIVATE_SEED_SIZE (32)1022810229#define SYMCRYPT_COMPOSITE_MLKEM_LAMPS_PRIVATE_KEY_SIZE_MLKEM768_P256 (115)10230#define SYMCRYPT_COMPOSITE_MLKEM_LAMPS_PRIVATE_KEY_SIZE_MLKEM768_X25519 (96)10231#define SYMCRYPT_COMPOSITE_MLKEM_LAMPS_PRIVATE_KEY_SIZE_MLKEM1024_P384 (128)1023210233#define SYMCRYPT_COMPOSITE_MLKEM_PUBLIC_KEY_SIZE_MLKEM768_P256 (1249)10234#define SYMCRYPT_COMPOSITE_MLKEM_PUBLIC_KEY_SIZE_MLKEM768_X25519 (1216)10235#define SYMCRYPT_COMPOSITE_MLKEM_PUBLIC_KEY_SIZE_MLKEM1024_P384 (1665)102361023710238SYMCRYPT_ERROR10239SYMCRYPT_CALL10240SymCryptCompositeMlKemSizeofKeyFormatFromParams(10241SYMCRYPT_COMPOSITE_MLKEM_PARAMS params,10242SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT compositeMlKemkeyformat,10243_Out_ SIZE_T* pcbKeyFormat );10244//10245// Gives the size in bytes of the blob of the given format for the given Composite ML-KEM10246// parameters via pcbKeyFormat output.10247// Returns SYMCRYPT_INCOMPATIBLE_FORMAT if compositeMlKemkeyformat is an unsupported value,10248// or SYMCRYPT_INVALID_ARGUMENT if other parameters are invalid.10249//1025010251#define SYMCRYPT_COMPOSITE_MLKEM_CIPHERTEXT_SIZE_MLKEM768_P256 (1153)10252#define SYMCRYPT_COMPOSITE_MLKEM_CIPHERTEXT_SIZE_MLKEM768_X25519 (1120)10253#define SYMCRYPT_COMPOSITE_MLKEM_CIPHERTEXT_SIZE_MLKEM1024_P384 (1665)1025410255SYMCRYPT_ERROR10256SYMCRYPT_CALL10257SymCryptCompositeMlKemSizeofCiphertextFromParams(10258SYMCRYPT_COMPOSITE_MLKEM_PARAMS params,10259_Out_ SIZE_T* pcbCiphertext );10260//10261// Gives the size in bytes of the ciphertext for the given Composite ML-KEM parameters.10262// Returns SYMCRYPT_INVALID_ARGUMENT if parameters are invalid.10263//1026410265SYMCRYPT_ERROR10266SYMCRYPT_CALL10267SymCryptCompositeMlKemkeyGenerate(10268_Inout_ PSYMCRYPT_COMPOSITE_MLKEMKEY pkCompositeMlKemkey,10269UINT32 flags );10270//10271// Generate a new random Composite ML-KEM key using the information from the10272// parameters passed to SymCryptCompositeMlKemkeyAllocate.10273//10274// Allowed flags:10275//10276// - SYMCRYPT_FLAG_KEY_NO_FIPS10277// Opt-out of performing validation required for FIPS10278//10279// Described in more detail in the "Flags for asymmetric key generation and import" section above10280//1028110282SYMCRYPT_ERROR10283SYMCRYPT_CALL10284SymCryptCompositeMlKemkeySetValue(10285_In_reads_bytes_( cbSrc ) PCBYTE pbSrc,10286SIZE_T cbSrc,10287SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT compositeMlKemkeyFormat,10288UINT32 flags,10289_Inout_ PSYMCRYPT_COMPOSITE_MLKEMKEY pkCompositeMlKemkey );10290//10291// Import key material to a Composite ML-KEM key object. The arguments are the following:10292// - (pbSrc, cbSrc): a buffer containing a representation of a Composite ML-KEM key,10293// in format specified by compositeMlKemkeyFormat.10294// - compositeMlKemkeyFormat format of the input10295//10296// Allowed flags:10297//10298// - SYMCRYPT_FLAG_KEY_NO_FIPS10299// Opt-out of performing validation required for FIPS10300//10301// - SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION10302// Opt-out of performing almost all validation - must be specified with SYMCRYPT_FLAG_KEY_NO_FIPS10303//10304// Remarks:10305// - cbSrc must be equal to the cbKeyFormat returned from10306// SymCryptCompositeMlKemSizeofKeyFormatFromParams(params, compositeMlKemkeyFormat, &cbKeyFormat), though10307// typically this value can be known statically (see definition of SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT)10308//1030910310SYMCRYPT_ERROR10311SYMCRYPT_CALL10312SymCryptCompositeMlKemkeyGetValue(10313_In_ PCSYMCRYPT_COMPOSITE_MLKEMKEY pkCompositeMlKemkey,10314_Out_writes_bytes_( cbDst ) PBYTE pbDst,10315SIZE_T cbDst,10316SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT compositeMlKemkeyFormat,10317UINT32 flags );10318//10319// Export key material from a Composite ML-KEM key object. The arguments are the following:10320// - (pbDst, cbDst): a buffer into which a representation of a Composite ML-KEM key is10321// written, in the format specified by compositeMlKemkeyFormat.10322// - compositeMlKemkeyFormat format of the output10323//10324// Allowed flags:10325// - None.10326//10327// Remarks:10328// - If the key object does not have the information required to export to the format10329// specified by compositeMlKemkeyFormat this function will return SYMCRYPT_INCOMPATIBLE_FORMAT.10330// - cbDst must be equal to the cbKeyFormat returned from10331// SymCryptCompositeMlKemSizeofKeyFormatFromParams(params, compositeMlKemkeyFormat, &cbKeyFormat), though typically this10332// value can be known statically (see definition of SYMCRYPT_COMPOSITE_MLKEMKEY_FORMAT)10333//1033410335SYMCRYPT_ERROR10336SYMCRYPT_CALL10337SymCryptCompositeMlKemEncapsulate(10338_In_ PCSYMCRYPT_COMPOSITE_MLKEMKEY pkCompositeMlKemkey,10339_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,10340SIZE_T cbAgreedSecret,10341_Out_writes_bytes_( cbCiphertext ) PBYTE pbCiphertext,10342SIZE_T cbCiphertext );10343//10344// Performs the Encapsulate operation of Composite ML-KEM.10345// This uses the public information of a Composite ML-KEM keypair to generate an agreed secret10346// and a ciphertext. Only a peer with the private information of a Composite ML-KEM keypair can10347// decapsulate the ciphertext to compute the agreed secret.10348//10349// The arguments are the following:10350// - pkCompositeMlKemkey: a key which contains public information required for encapsulation.10351// - (pbAgreedSecret, cbAgreedSecret): a buffer into which the generated secret is written.10352// Currently cbAgreedSecret must be 32 for all parameterizations of Composite ML-KEM.10353// - (pbCiphertext, cbCiphertext): a buffer into which the encapsulated secret is written.10354// cbCiphertext must equal cbCiphertext given by SymCryptCompositeMlKemSizeofCiphertextFromParams,10355// though typically this value can be known statically (see definition of10356// SYMCRYPT_COMPOSITE_MLKEM_CIPHERTEXT_SIZE_*).10357//1035810359SYMCRYPT_ERROR10360SYMCRYPT_CALL10361SymCryptCompositeMlKemDecapsulate(10362_In_ PCSYMCRYPT_COMPOSITE_MLKEMKEY pkCompositeMlKemkey,10363_In_reads_bytes_( cbCiphertext ) PCBYTE pbCiphertext,10364SIZE_T cbCiphertext,10365_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,10366SIZE_T cbAgreedSecret );10367//10368// Performs the Decapsulate operation of Composite ML-KEM.10369// This uses the private information of a Composite ML-KEM keypair to generate an agreed10370// secret from a ciphertext.10371//10372// The arguments are the following:10373// - pkCompositeMlKemkey: a key which contains private information required for decapsulation.10374// - (pbCiphertext, cbCiphertext): a buffer containing an encapsulated secret.10375// cbCiphertext must equal cbCiphertext given by SymCryptCompositeMlKemSizeofCiphertextFromParams,10376// though typically this value can be known statically (see definition of10377// SYMCRYPT_COMPOSITE_MLKEM_CIPHERTEXT_SIZE_*).10378// - (pbAgreedSecret, cbAgreedSecret): a buffer into which the generated secret is written.10379// Currently cbAgreedSecret must be 32 for all parameterizations of Composite ML-KEM.10380//10381// Note: Given an invalid, but correctly-sized, ciphertext, the Composite ML-KEM Decapsulation operation10382// will "implicitly reject" the ciphertext, by returning success in equal time to a valid10383// decapsulation operation, with pseudo-random agreed secret output. This forces higher10384// level protocols to fail later when symmetric keys of peers do not match.10385// So decapsulate will only ever return an error if there are programming errors (e.g. incorrect size),10386// or something fundamentally goes wrong with the environment (e.g. internal memory allocation fails).10387//1038810389////////////////////////////////////////////////////////////10390// Module-Lattice-Based Digital Signature Algorithm (ML-DSA)10391////////////////////////////////////////////////////////////1039210393// Maximum length of the context string used in signing and verification10394#define SYMCRYPT_MLDSA_CONTEXT_MAX_LENGTH (255)1039510396// ML-DSA key formats10397// ==================10398// The below formats apply **only to external formats**: When somebody is importing or exporting10399// a key. The internal format of the keys is not visible to the caller.10400typedef enum _SYMCRYPT_MLDSAKEY_FORMAT {10401SYMCRYPT_MLDSAKEY_FORMAT_NULL = 0,10402SYMCRYPT_MLDSAKEY_FORMAT_PRIVATE_SEED = 1,10403// 32-byte private root seed xi from which all other parameters can be derived.10404// On its own it is ambiguous which ML-DSA parameter set this represents; callers wanting to10405// store this format must track the parameter set alongside the key.10406SYMCRYPT_MLDSAKEY_FORMAT_PRIVATE_KEY = 2,10407// Standard byte encoding of an ML-DSA private key, per FIPS 204.10408// Size is 2560, 4032, or 4896 bytes for ML-DSA 44, 65, and 87 respectively.10409SYMCRYPT_MLDSAKEY_FORMAT_PUBLIC_KEY = 3,10410// Standard byte encoding of an ML-DSA public key, per FIPS 204.10411// Size is 1312, 1952, or 2592 bytes for ML-DSA 44, 65, and 87 respectively.10412} SYMCRYPT_MLDSAKEY_FORMAT;1041310414typedef enum _SYMCRYPT_MLDSA_PARAMS {10415SYMCRYPT_MLDSA_PARAMS_NULL = 0,10416SYMCRYPT_MLDSA_PARAMS_MLDSA44 = 1,10417SYMCRYPT_MLDSA_PARAMS_MLDSA65 = 2,10418SYMCRYPT_MLDSA_PARAMS_MLDSA87 = 3,10419} SYMCRYPT_MLDSA_PARAMS;10420// Currently supported ML-DSA parameter sets are represented externally only by the enum1042110422typedef enum _SYMCRYPT_PQDSA_HASH_ID {10423SYMCRYPT_PQDSA_HASH_ID_NULL = 0,10424SYMCRYPT_PQDSA_HASH_ID_SHA256 = 1,10425SYMCRYPT_PQDSA_HASH_ID_SHA384 = 2,10426SYMCRYPT_PQDSA_HASH_ID_SHA512 = 3,10427SYMCRYPT_PQDSA_HASH_ID_SHA512_256 = 4,10428SYMCRYPT_PQDSA_HASH_ID_SHA3_256 = 5,10429SYMCRYPT_PQDSA_HASH_ID_SHA3_384 = 6,10430SYMCRYPT_PQDSA_HASH_ID_SHA3_512 = 7,10431SYMCRYPT_PQDSA_HASH_ID_SHAKE128 = 8,10432SYMCRYPT_PQDSA_HASH_ID_SHAKE256 = 9,10433} SYMCRYPT_PQDSA_HASH_ID;10434// Supported hash algorithms for use with Hash-ML-DSA1043510436//========================================================================10437// MLDSAKEY objects' API10438//1043910440SYMCRYPT_ERROR10441SYMCRYPT_CALL10442SymCryptMlDsaSizeofKeyFormatFromParams(10443SYMCRYPT_MLDSA_PARAMS params,10444SYMCRYPT_MLDSAKEY_FORMAT mlDsakeyFormat,10445_Out_ SIZE_T* pcbKeyFormat );10446//10447// Gives the size in bytes of the blob of the given format for the given ML-DSA10448// parameters and the specified format via pcbKeyFormat output.10449//10450// Return values:10451// - SYMCRYPT_NO_ERROR on success.10452// - SYMCRYPT_INCOMPATIBLE_FORMAT if mlDsakeyFormat is an unsupported value.10453// - SYMCRYPT_INVALID_ARGUMENT if other parameters are invalid.10454//1045510456#define SYMCRYPT_MLDSA_SIGNATURE_SIZE_MLDSA44 (2420)10457#define SYMCRYPT_MLDSA_SIGNATURE_SIZE_MLDSA65 (3309)10458#define SYMCRYPT_MLDSA_SIGNATURE_SIZE_MLDSA87 (4627)1045910460SYMCRYPT_ERROR10461SYMCRYPT_CALL10462SymCryptMlDsaSizeofSignatureFromParams(10463SYMCRYPT_MLDSA_PARAMS params,10464_Out_ SIZE_T* pcbSignature );10465//10466// Gives the size in bytes of the signature for the given ML-DSA parameters.10467//10468// Return values:10469// - SYMCRYPT_NO_ERROR on success.10470// - SYMCRYPT_INVALID_ARGUMENT if parameters are invalid.10471//1047210473_Success_( return != NULL )10474PSYMCRYPT_MLDSAKEY10475SYMCRYPT_CALL10476SymCryptMlDsakeyAllocate(10477SYMCRYPT_MLDSA_PARAMS params );10478//10479// Allocate a new ML-DSA key object sized according to the parameters.10480//10481// This call does not generate key material. It should be followed by a call to10482// SymCryptMlDsakeyGenerate or SymCryptMlDsakeySetValue.10483//10484// May return NULL if memory allocation fails.10485//1048610487VOID10488SYMCRYPT_CALL10489SymCryptMlDsakeyFree(10490_Post_invalid_ PSYMCRYPT_MLDSAKEY pkMlDsakey );10491//10492// Free an ML-DSA key object that was allocated with SymCryptMlDsakeyAllocate.10493//1049410495SYMCRYPT_ERROR10496SYMCRYPT_CALL10497SymCryptMlDsakeyGenerate(10498_Inout_ PSYMCRYPT_MLDSAKEY pkMlDsakey,10499UINT32 flags );10500//10501// Generate a new random ML-DSA key using the information from the10502// parameters passed to SymCryptMlDsakeyAllocate.10503//10504// Parameters:10505// - pkMlDsakey: a pointer to an ML-DSA key object allocated with SymCryptMlDsakeyAllocate10506//10507// Allowed flags:10508//10509// - SYMCRYPT_FLAG_KEY_NO_FIPS10510// Opt-out of performing validation required for FIPS10511//10512// Return values:10513// - SYMCRYPT_NO_ERROR on success.10514// - SYMCRYPT_MEMORY_ALLOCATION_FAILURE if memory allocation fails.10515//1051610517SYMCRYPT_ERROR10518SYMCRYPT_CALL10519SymCryptMlDsakeySetValue(10520_In_reads_bytes_( cbSrc ) PCBYTE pbSrc,10521SIZE_T cbSrc,10522SYMCRYPT_MLDSAKEY_FORMAT mlDsakeyFormat,10523UINT32 flags,10524_Inout_ PSYMCRYPT_MLDSAKEY pkMlDsakey );10525//10526// Import key material to an ML-DSA key object from a byte blob.10527//10528// Parameters:10529// - (pbSrc, cbSrc): a buffer containing a representation of an ML-DSA key, in the format specified10530// by the format parameter.10531// - mlDsakeyFormat: format of the input10532// - pkMlDsakey: a pointer to an ML-DSA key object allocated with SymCryptMlDsakeyAllocate.10533//10534// Allowed flags:10535//10536// - SYMCRYPT_FLAG_KEY_NO_FIPS10537// Opt-out of performing validation required for FIPS10538//10539// Remarks:10540// - cbSrc must be equal to the cbKeyFormat returned from10541// SymCryptMlDsaSizeofKeyFormatFromParams(params, format, &cbKeyFormat), though typically this10542// value can be known statically (see definition of SYMCRYPT_MLDSAKEY_FORMAT)10543//10544// Return values:10545// - SYMCRYPT_NO_ERROR on success.10546// - SYMCRYPT_INCOMPATIBLE_FORMAT if the key format is invalid.10547// - SYMCRYPT_INVALID_ARGUMENT if other arguments are invalid.10548// - SYMCRYPT_WRONG_KEY_SIZE if cbSrc does not match the expected size for the key format.10549// - SYMCRYPT_INVALID_BLOB if the encoded key is invalid.10550// - SYMCRYPT_MEMORY_ALLOCATION_FAILURE if memory allocation fails.10551//1055210553SYMCRYPT_ERROR10554SYMCRYPT_CALL10555SymCryptMlDsakeyGetValue(10556_In_ PCSYMCRYPT_MLDSAKEY pkMlDsakey,10557_Out_writes_bytes_( cbDst ) PBYTE pbDst,10558SIZE_T cbDst,10559SYMCRYPT_MLDSAKEY_FORMAT mlDsakeyFormat,10560UINT32 flags );10561//10562// Export key material from an ML-DSA key object to a byte blob.10563//10564// Parameters:10565// - pkMlDsakey: pointer to a valid ML-DSA key object.10566// - (pbDst, cbDst): buffer for the exported ML-DSA key, in the format specified by the format10567// parameter.10568// - mlDsakeyFormat: format of the output10569// - flags: no flags are currently defined; must be set to 010570//10571// Return values:10572// - SYMCRYPT_NO_ERROR on success.10573// - SYMCRYPT_INCOMPATIBLE_FORMAT if the key object does not have the information required to export10574// the format specified by mlDsakeyFormat.10575// - SYMCRYPT_INVALID_ARGUMENT if the output buffer size or other arguments are incorrect.10576//10577// Remarks:10578// - cbDst must be equal to the cbKeyFormat returned from10579// SymCryptMlDsaSizeofKeyFormatFromParams(params, format, &cbKeyFormat), though typically this10580// value can be known statically (see definition of SYMCRYPT_MLDSAKEY_FORMAT)10581//1058210583SYMCRYPT_ERROR10584SYMCRYPT_CALL10585SymCryptMlDsaSign(10586_In_ PCSYMCRYPT_MLDSAKEY pkMlDsakey,10587_In_reads_bytes_( cbMessage ) PCBYTE pbMessage,10588SIZE_T cbMessage,10589_In_reads_bytes_opt_( cbContext ) PCBYTE pbContext,10590_In_range_( 0, SYMCRYPT_MLDSA_CONTEXT_MAX_LENGTH ) SIZE_T cbContext,10591UINT32 flags,10592_Out_writes_bytes_( cbSignature ) PBYTE pbSignature,10593SIZE_T cbSignature );10594//10595// Sign a message using "pure" ML-DSA. The message can be of arbitrary length.10596//10597// Parameters:10598// - pkMlDsakey: an ML-DSA key object. Must contain the private key material.10599// - (pbMessage, cbMessage): the message to sign. May be of arbitrary length.10600// - (pbContext, cbContext): an optional context string which will be included in the message10601// representative to be signed. Length must be <= SYMCRYPT_MLDSA_CONTEXT_MAX_LENGTH.10602// - flags: no flags are currently defined; must be set to 010603// - (pbSignature, cbSignature): the buffer into which the signature is written.10604//10605// Return values:10606// - SYMCRYPT_NO_ERROR on success.10607// - SYMCRYPT_INVALID_ARGUMENT if the key object does not contain a private key, or if other10608// parameters are invalid.10609// - SYMCRYPT_MEMORY_ALLOCATION_FAILURE if memory allocation fails.10610//10611// Remarks:10612// cbSignature must be equal to the cbKeyFormat returned from10613// SymCryptMlDsaSizeofSignatureFromParams( params, &cbSignature ), though typically this10614// value can be known statically (see definition of SYMCRYPT_MLDSA_SIGNATURE_SIZE_*).10615//1061610617SYMCRYPT_ERROR10618SYMCRYPT_CALL10619SymCryptExternalMuMlDsaSign(10620_In_ PCSYMCRYPT_MLDSAKEY pkMlDsakey,10621_In_reads_bytes_( cbMu ) PCBYTE pbMu,10622SIZE_T cbMu,10623UINT32 flags,10624_Out_writes_bytes_( cbSignature ) PBYTE pbSignature,10625SIZE_T cbSignature );10626//10627// Sign a precomputed message representative Mu.10628//10629// Parameters:10630// - (pbMu, cbMu): the message representative to sign,10631// which must be of size 64 (SYMCRYPT_SHAKE256_RESULT_SIZE).10632// - All other parameters are the same as for SymCryptMlDsaSign.10633//1063410635SYMCRYPT_ERROR10636SYMCRYPT_CALL10637SymCryptHashMlDsaSign(10638_In_ PCSYMCRYPT_MLDSAKEY pkMlDsakey,10639SYMCRYPT_PQDSA_HASH_ID hashAlg,10640_In_reads_bytes_( cbHash ) PCBYTE pbHash,10641SIZE_T cbHash,10642_In_reads_bytes_opt_( cbContext ) PCBYTE pbContext,10643_In_range_( 0, SYMCRYPT_MLDSA_CONTEXT_MAX_LENGTH ) SIZE_T cbContext,10644UINT32 flags,10645_Out_writes_bytes_( cbSignature ) PBYTE pbSignature,10646SIZE_T cbSignature );10647//10648// Sign a message using "pre-hash" ML-DSA. The caller precomputes the hash of the message.10649//10650// Parameters:10651// - hashAlg: the ID of the hash algorithm used to compute pbHash.10652// - (pbHash, cbHash): the hash of the message to sign.10653// - All other parameters are the same as for SymCryptMlDsaSign.10654//10655// Return values:10656// - SYMCRYPT_NO_ERROR on success.10657// - SYMCRYPT_INVALID_ARGUMENT if the key object does not contain a private key, or if other10658// parameters are invalid.10659// - SYMCRYPT_MEMORY_ALLOCATION_FAILURE if memory allocation fails.10660//10661// Remarks:10662// The hash algorithm provided must meet the minimum required collision strength defined for the10663// chosen ML-DSA parameter set. This is the lambda parameter in FIPS 204. This means that the10664// following hash algorithms are supported:10665//10666// ML-DSA-44 (lambda = 128): SHA-256, SHA-384, SHA-512, SHA-512/256, SHA3-256, SHA3-384, SHA3-512, SHAKE128, SHAKE25610667// ML-DSA-65 (lambda = 192): SHA-384, SHA-512, SHA3-384, SHA3-512, SHAKE25610668// ML-DSA-87 (lambda = 256): SHA-512, SHA3-512, SHAKE25610669//10670// Additionally, cbHash must match the output length of the hash algorithm.10671// For XOFs, the any output length >= the minimum collision strength is acceptable. If this10672// requirement is not met, the function returns SYMCRYPT_INVALID_ARGUMENT.10673//10674// As with SymCryptMlDsaSign, cbSignature must be equal to the cbKeyFormat returned from10675// SymCryptMlDsaSizeofSignatureFromParams( params, &cbSignature ), though typically this10676// value can be known statically (see definition of SYMCRYPT_MLDSA_SIGNATURE_SIZE_*).10677//1067810679SYMCRYPT_ERROR10680SYMCRYPT_CALL10681SymCryptMlDsaVerify(10682_In_ PCSYMCRYPT_MLDSAKEY pkMlDsakey,10683_In_reads_bytes_( cbMessage ) PCBYTE pbMessage,10684SIZE_T cbMessage,10685_In_reads_bytes_opt_( cbContext ) PCBYTE pbContext,10686_In_range_( 0, SYMCRYPT_MLDSA_CONTEXT_MAX_LENGTH ) SIZE_T cbContext,10687_In_reads_bytes_( cbSignature ) PCBYTE pbSignature,10688SIZE_T cbSignature,10689UINT32 flags );10690//10691// Verify a signature using "pure" ML-DSA. The message can be of arbitrary length.10692//10693// Parameters:10694// - pkMlDsakey: the ML-DSA key object used to verify the signature.10695// - (pbMessage, cbMessage): the message that the signature was generated from.10696// - (pbContext, cbContext): an optional context string which will be included in the message10697// representative to be signed. Length must be <= SYMCRYPT_MLDSA_CONTEXT_MAX_LENGTH.10698// - (pbSignature, cbSignature): the signature to verify.10699// - flags: no flags are currently defined; must be set to 010700//10701// Return values:10702// - SYMCRYPT_NO_ERROR if the signature was verified successfully.10703// - SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE if the signature is invalid.10704// - SYMCRYPT_INVALID_ARGUMENT if the parameters are invalid.1070510706SYMCRYPT_ERROR10707SYMCRYPT_CALL10708SymCryptExternalMuMlDsaVerify(10709_In_ PCSYMCRYPT_MLDSAKEY pkMlDsakey,10710_In_reads_bytes_( cbMu ) PCBYTE pbMu,10711SIZE_T cbMu,10712_In_reads_bytes_( cbSignature ) PCBYTE pbSignature,10713SIZE_T cbSignature,10714UINT32 flags );10715//10716// Verify a signature of a precomputed message representative Mu.10717//10718// Parameters:10719// - (pbMu, cbMu): the message representative that was signed,10720// which must be of size 64 (SYMCRYPT_SHAKE256_RESULT_SIZE).10721// - All other parameters are the same as for SymCryptMlDsaVerify.10722//1072310724SYMCRYPT_ERROR10725SYMCRYPT_CALL10726SymCryptHashMlDsaVerify(10727_In_ PCSYMCRYPT_MLDSAKEY pkMlDsakey,10728SYMCRYPT_PQDSA_HASH_ID hashAlg,10729_In_reads_bytes_( cbHash ) PCBYTE pbHash,10730SIZE_T cbHash,10731_In_reads_bytes_opt_( cbContext ) PCBYTE pbContext,10732_In_range_( 0, SYMCRYPT_MLDSA_CONTEXT_MAX_LENGTH ) SIZE_T cbContext,10733_In_reads_bytes_( cbSignature ) PCBYTE pbSignature,10734SIZE_T cbSignature,10735UINT32 flags );10736//10737// Verify a signature using "pre-hash" ML-DSA. The caller precomputes the hash of the message.10738//10739// Parameters:10740// - hashAlg: the ID of the hash algorithm used to compute pbHash.10741// - (pbHash, cbHash): the hash of the message that the signature was generated from.10742// - All other parameters are the same as for SymCryptMlDsaVerify.10743//10744// Return values:10745// - SYMCRYPT_NO_ERROR if the signature was validated successfully.10746// - SYMCRYPT_SIGNATURE_VERIFICATION_FAILURE if the signature is invalid.10747// - SYMCRYPT_INVALID_ARGUMENT if the parameters are invalid.10748//10749// Remarks:10750// See the remarks for SymCryptHashMlDsaSign regarding the required security strength of the hash10751// algorithm. For unsupported hash algorithms, the function will return SYMCRYPT_INVALID_ARGUMENT.1075210753VOID10754SYMCRYPT_CALL10755SymCryptMlDsaSelftest( void );10756//10757// FIPS selftest for ML-DSA10758//1075910760_Analysis_noreturn_10761VOID10762SYMCRYPT_CALL10763SymCryptFatal( UINT32 fatalCode );10764//10765// Call the Fatal routine passed to the library upon initialization10766// We use the SYMCRYPT_ASSERT macro to catch problems in Debug builds10767//107681076910770typedef struct _SYMCRYPT_UINT32_MAP {10771UINT32 from; // map this value...10772UINT32 to; // ...into this value10773} SYMCRYPT_UINT32_MAP, *PSYMCRYPT_UINT32_MAP;10774typedef const SYMCRYPT_UINT32_MAP * PCSYMCRYPT_UINT32_MAP;107751077610777UINT3210778SYMCRYPT_CALL10779SymCryptMapUint32(10780UINT32 u32Input,10781UINT32 u32Default,10782_In_reads_( nMap ) PCSYMCRYPT_UINT32_MAP pcMap,10783SIZE_T nMap );10784//10785// Map values in a side-channel safe way, typically used for mapping error codes.10786//10787// (pcMap, nMap) point to an array of nMap entries of type SYMCRYPT_UINT32_MAP;10788// each entry specifies a single mapping. If u32Input matches the10789// 'from' field, the return value will be the 'to' field value.10790// If u32Input is not equal to any 'from' field values, the return value is u32Default.10791// Both u32Input and the return value are treated as secrets w.r.t. side channels.10792//10793// If multiple map entries have the same 'from' field value, then the return value10794// is one of the several 'to' field values; which one is not defined.10795//10796// This function is particularly useful when mapping error codes in situations where10797// the actual error cannot be revealed through side channels.1079810799#if SYMCRYPT_DEBUG10800#define SYMCRYPT_ASSERT( _x ) \10801{\10802if( !(_x) ){ SymCryptFatal( 'asrt' ); }\10803}\10804_Analysis_assume_( _x )10805#else10806#define SYMCRYPT_ASSERT( _x ) \10807_Analysis_assume_( _x )10808#endif108091081010811#ifdef __cplusplus10812}10813#endif108141081510816