SymCrypt/unittest/inc/algorithm_base.h

2100 строки
76 KiB
C++

//
// Algorithm_base.h
// base classes for algorithm implementations
//
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
//
//
// AlgorithmImplementation class
// This is the abstract class that represents the common properties
// of all algorithm implementations.
//
class AlgorithmImplementation
{
public:
AlgorithmImplementation();
virtual ~AlgorithmImplementation() {};
private:
AlgorithmImplementation( const AlgorithmImplementation & );
VOID operator =( const AlgorithmImplementation & );
public:
std::string m_algorithmName; // Name of algorithm
std::string m_modeName; // Name of algorithm mode
std::string m_implementationName; // Name of implementation
virtual VOID setPerfKeySize( SIZE_T keySize ) {UNREFERENCED_PARAMETER(keySize);};
PerfKeyFn m_perfKeyFunction;
PerfDataFn m_perfDataFunction;
PerfDataFn m_perfDecryptFunction;
PerfCleanFn m_perfCleanFunction;
//
// During functional testing we test all implementations of a single algorithm
// in parallel. This makes debugging bugs triggered by the pseudo-random test cases
// much easier.
// When we check the (intermediate or final) result there are three types of errors we can encounter:
// - Result disagrees with majority of other implementations of the same algorithm
// - Results disagree but there is no majority to find out what result is correct
// - Result agrees with majority but not with KAT values.
//
// These counters count how often each of these cases happens.
//
ULONGLONG m_nErrorDisagreeWithMajority;
ULONGLONG m_nErrorNoMajority;
ULONGLONG m_nErrorKatFailure;
//
// Number of times this algorithm has produced a result during the test
//
ULONGLONG m_nResults;
//
// Performance information
//
typedef struct _ALG_PERF_INFO
{
SIZE_T keySize; // key size to add to row header. (0 if not used)
SIZE_T dataSize; // data size to add to row header. (only used with g_measure_specific_sizes)
char * operationName; // operation name string, must be 3 characters long
char * strPostfix; // postfix string, it is a string associated with a special key size for the given algorithm (i.e. data unit size, elliptic curve type, modulus type, etc.)
double cFixed; // clocks of fixed overhead.
double cPerByte; // clocks average cost per byte (used only for linear records, 0 for non-linear records)
double cRange; // 90 percentile of deviation from prediction by previous two numbers
} ALG_PERF_INFO;
std::vector<ALG_PERF_INFO> m_perfInfo;
};
class HashImplementation: public AlgorithmImplementation
{
public:
HashImplementation() {};
virtual ~HashImplementation() {};
private:
HashImplementation( const HashImplementation & );
VOID operator=( const HashImplementation & );
public:
virtual SIZE_T resultLen() = 0;
// Return the result length of this hash
virtual SIZE_T inputBlockLen() = 0;
// Return the input block length of this hash
virtual VOID init() = 0;
// Initialize for a new hash computation.
virtual VOID append( _In_reads_( cbData ) PCBYTE pbData, SIZE_T cbData ) = 0;
// Append data to the running hash computation.
virtual VOID result( _Out_writes_( cbResult ) PBYTE pbResult, SIZE_T cbResult ) = 0;
// Get the result of the running hash computation.
virtual VOID hash( _In_reads_( cbData ) PCBYTE pbData, SIZE_T cbData,
_Out_writes_( cbResult ) PBYTE pbResult, SIZE_T cbResult );
// Single hash computation.
// The default implementation calls init/append/result so implementations that do not
// have a separate compute-hash function can call the generic implementation in this
// class.
virtual NTSTATUS initWithLongMessage( ULONGLONG nBytes ) = 0;
// nBytes is a multiple of the input block length.
// Set the computation to the state as if it has processed a message nBytes long
// which resulted in the internal chaining state having the value with every
// byte equal to the character 'b'.
// This allows us to test carry-handling of the message length counters. (A known
// problem area.)
// Return zero if success, NT status error if not supported.
virtual NTSTATUS exportSymCryptFormat(
_Out_writes_bytes_to_( cbResultBufferSize, *pcbResult ) PBYTE pbResult,
_In_ SIZE_T cbResultBufferSize,
_Out_ SIZE_T *pcbResult ) = 0;
};
class XofImplementation : public AlgorithmImplementation
{
public:
XofImplementation() {};
virtual ~XofImplementation() {};
private:
XofImplementation(const XofImplementation&);
VOID operator=(const XofImplementation&);
public:
virtual SIZE_T inputBlockLen() = 0;
// Return the input block length of this XOF
virtual VOID init() = 0;
// Initialize for a new XOF computation.
virtual VOID append(_In_reads_(cbData) PCBYTE pbData, SIZE_T cbData) = 0;
// Append data to the running XOF computation.
virtual VOID extract(_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult, BOOLEAN bWipe) = 0;
// XOF extraction.
// Extracts cbResult bytes from the XOF. Wipes and re-initializes the state if bWipe=TRUE.
virtual VOID result(_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult) = 0;
// Get the result of the running XOF computation.
// Default implementation calls extract with bWipe=TRUE.
virtual VOID xof(_In_reads_(cbData) PCBYTE pbData, SIZE_T cbData,
_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult);
// Single-call XOF computation.
// The default implementation calls init/append/result.
};
class CustomizableXofImplementation : public AlgorithmImplementation
{
public:
CustomizableXofImplementation() {};
virtual ~CustomizableXofImplementation() {};
private:
CustomizableXofImplementation(const CustomizableXofImplementation&);
VOID operator=(const CustomizableXofImplementation&);
public:
virtual SIZE_T inputBlockLen() = 0;
// Return the input block length of this XOF
virtual VOID init( _In_reads_(cbNstr) PCBYTE pbNstr,
SIZE_T cbNstr,
_In_reads_(cbSstr) PCBYTE pbSstr,
SIZE_T cbSstr) = 0;
// Initialize for a new XOF computation.
virtual VOID append(_In_reads_(cbData) PCBYTE pbData, SIZE_T cbData) = 0;
// Append data to the running XOF computation.
virtual VOID extract(_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult, BOOLEAN bWipe) = 0;
// XOF extraction.
// Extracts cbResult bytes from the XOF. Wipes and re-initializes the state if bWipe=TRUE.
virtual VOID result(_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult) = 0;
// Get the result of the running XOF computation.
// Default implementation calls extract with bWipe=TRUE.
virtual VOID xof(
_In_reads_( cbNstr ) PCBYTE pbNstr, SIZE_T cbNstr,
_In_reads_( cbSstr ) PCBYTE pbSstr, SIZE_T cbSstr,
_In_reads_( cbData ) PCBYTE pbData, SIZE_T cbData,
_Out_writes_( cbResult ) PBYTE pbResult, SIZE_T cbResult) = 0;
// Single-call XOF computation.
// The default implementation calls init/append/result.
};
#define MAX_PARALLEL_HASH_STATES 32
#define MAX_PARALLEL_HASH_OPERATIONS 128
class ParallelHashImplementation: public AlgorithmImplementation
{
public:
ParallelHashImplementation() {};
virtual ~ParallelHashImplementation() {};
private:
ParallelHashImplementation( const ParallelHashImplementation & );
VOID operator=( const ParallelHashImplementation & );
public:
virtual PCSYMCRYPT_HASH SymCryptHash() = 0;
// Return a pointer to the SymCrypt implementation of the equivalent hash algorithm.
virtual SIZE_T resultLen() = 0;
// Return the result length of this hash
virtual SIZE_T inputBlockLen() = 0;
// Return the input block length of this hash
virtual VOID init( SIZE_T nHashes ) = 0;
// Initialize for a new hash computation.
// nHashes = # hash states, nHashes <= MAX_PARALLEL_HASH_STATES
virtual VOID process(
_In_reads_( nOperations ) BCRYPT_MULTI_HASH_OPERATION * pOperations,
SIZE_T nOperations ) = 0;
// Process BCrypt-style operations on the parallel hash state
virtual NTSTATUS initWithLongMessage( ULONGLONG nBytes ) = 0;
// nBytes is a multiple of the input block length.
// Set the computation to the state as if it has processed a message nBytes long
// which resulted in the internal chaining state having the value with every
// byte equal to the character 'b'.
// This allows us to test carry-handling of the message length counters. (A known
// problem area.)
// Return zero if success, NT status error if not supported.
};
class MacImplementation: public AlgorithmImplementation
{
public:
MacImplementation() {};
~MacImplementation() {};
private:
MacImplementation( const MacImplementation & );
VOID operator=( const MacImplementation & );
public:
virtual SIZE_T resultLen() = 0;
// return the result length of this MAC
virtual SIZE_T inputBlockLen() = 0;
// return the input block length of this MAC
virtual NTSTATUS init( _In_reads_( cbKey ) PCBYTE pbKey, SIZE_T cbKey ) = 0;
// Start a new MAC computation with the given key.
// Return zero if success, NT status error if not supported.
virtual VOID append( _In_reads_( cbData ) PCBYTE pbData, SIZE_T cbData ) = 0;
// Append data to the running MAC computation.
virtual VOID result( _Out_writes_( cbResult ) PBYTE pbResult, SIZE_T cbResult ) = 0;
// Get the result of the running MAC computation.
virtual NTSTATUS mac( _In_reads_( cbKey ) PCBYTE pbKey, SIZE_T cbKey,
_In_reads_( cbData ) PCBYTE pbData, SIZE_T cbData,
_Out_writes_( cbResult ) PBYTE pbResult, SIZE_T cbResult );
// Complete a full MAC computation.
// The default implementation merely calls the init/append/result members.
// Return zero if success, NT status error if not supported.
};
class KmacImplementation : public AlgorithmImplementation
{
public:
KmacImplementation() {};
~KmacImplementation() {};
private:
KmacImplementation(const KmacImplementation&);
VOID operator=(const KmacImplementation&);
public:
virtual SIZE_T inputBlockLen() = 0;
// return the input block length of this MAC
virtual VOID init(
_In_reads_(cbCustomizationStr) PCBYTE pbCustomizationStr, SIZE_T cbCustomizationStr,
_In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey) = 0;
// Start a new MAC computation with the given key and customization string.
virtual VOID append(_In_reads_(cbData) PCBYTE pbData, SIZE_T cbData) = 0;
// Append data to the running MAC computation.
virtual VOID extract(_Out_writes_(cbData) PBYTE pbResult, SIZE_T cbResult, BOOLEAN bWipe) = 0;
// Extract data in XOF mode.
virtual VOID result(_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult) = 0;
// Get the result of the running MAC computation.
virtual VOID mac(
_In_reads_(cbCustomizationStr) PCBYTE pbCustomizationStr, SIZE_T cbCustomizationStr,
_In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey,
_In_reads_(cbData) PCBYTE pbData, SIZE_T cbData,
_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult);
// Complete a full MAC computation.
// The default implementation merely calls the init/append/result members.
virtual VOID xof(
_In_reads_(cbCustomizationStr) PCBYTE pbCustomizationStr, SIZE_T cbCustomizationStr,
_In_reads_(cbKey) PCBYTE pbKey, SIZE_T cbKey,
_In_reads_(cbData) PCBYTE pbData, SIZE_T cbData,
_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult);
// Generate a fixed size output in XOF mode.
// The default implementation merely calls the init/append/extract members.
};
class BlockCipherImplementation: public AlgorithmImplementation
//
// Implements block cipher encryption modes.
// Data is always a multiple of the block length.
// The chaining value is used for CBC/CTR/CFB/etc mode, but is length 0 for ECB
//
{
public:
BlockCipherImplementation() {};
virtual ~BlockCipherImplementation() {};
private:
BlockCipherImplementation( const BlockCipherImplementation & );
VOID operator=( const BlockCipherImplementation & );
public:
virtual SIZE_T msgBlockLen() = 0;
virtual SIZE_T chainBlockLen() = 0;
virtual SIZE_T coreBlockLen() = 0;
virtual NTSTATUS setKey( PCBYTE pbKey, SIZE_T cbKey ) = 0;
virtual VOID encrypt(
_Inout_updates_opt_( cbChain ) PBYTE pbChain,
SIZE_T cbChain,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData ) = 0;
virtual VOID decrypt(
_Inout_updates_opt_( cbChain ) PBYTE pbChain,
SIZE_T cbChain,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData ) = 0;
};
class AuthEncImplementation: public AlgorithmImplementation
//
// Implements authenticated encryption modes.
//
{
public:
AuthEncImplementation() {};
virtual ~AuthEncImplementation() {};
private:
AuthEncImplementation( const AuthEncImplementation & );
VOID operator=( const AuthEncImplementation & );
public:
virtual std::set<SIZE_T> getNonceSizes() = 0;
virtual std::set<SIZE_T> getTagSizes() = 0;
virtual std::set<SIZE_T> getKeySizes() = 0;
virtual NTSTATUS setKey( _In_reads_( cbKey ) PCBYTE pbKey, SIZE_T cbKey ) = 0;
// The encrypt/decrypt can be called in two ways.
// First: process an entire message in one call. This requires no flags.
// Second: incremental processing of a message.
// For incremental processing, the AUTHENC_FLAG_PARTIAL flag is passed to all
// calls that are part of the incremental processing.
// All authdata has to be passed in the first incremental call.
// The last incremental call is marked by a nonzero pbTag.
// setTotalCbData() must be called before each sequence of incremental calls.
// Implementations that don't do incremental processing can simply return
// STATUS_NOT_SUPPORTED for all incremental calls.
#define AUTHENC_FLAG_PARTIAL 1
virtual VOID setTotalCbData( SIZE_T cbData ) = 0; // Set total cbData up front for partial processing (used by CCM)
virtual NTSTATUS encrypt(
_In_reads_( cbNonce ) PCBYTE pbNonce,
SIZE_T cbNonce,
_In_reads_( cbAuthData ) PCBYTE pbAuthData,
SIZE_T cbAuthData,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData,
_Out_writes_( cbTag ) PBYTE pbTag,
SIZE_T cbTag,
ULONG flags ) = 0;
virtual NTSTATUS decrypt(
_In_reads_( cbNonce ) PCBYTE pbNonce,
SIZE_T cbNonce,
_In_reads_( cbAuthData ) PCBYTE pbAuthData,
SIZE_T cbAuthData,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData,
_In_reads_( cbTag ) PCBYTE pbTag,
SIZE_T cbTag,
ULONG flags ) = 0;
};
class XtsImplementation: public AlgorithmImplementation
{
public:
XtsImplementation() {};
virtual ~XtsImplementation() {};
private:
XtsImplementation( const XtsImplementation & );
VOID operator=( const XtsImplementation & );
public:
virtual NTSTATUS setKey( PCBYTE pbKey, SIZE_T cbKey, UINT32 flags ) = 0;
virtual NTSTATUS encrypt(
SIZE_T cbDataUnit,
ULONGLONG tweak,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData ) = 0;
// Return zero if success, NT status error if not supported.
virtual NTSTATUS decrypt(
SIZE_T cbDataUnit,
ULONGLONG tweak,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData ) = 0;
// Return zero if success, NT status error if not supported.
virtual NTSTATUS encryptWith128bTweak(
SIZE_T cbDataUnit,
_In_reads_( SYMCRYPT_AES_BLOCK_SIZE ) PCBYTE pbTweak,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData ) = 0;
// Return zero if success, NT status error if not supported.
virtual NTSTATUS decryptWith128bTweak(
SIZE_T cbDataUnit,
_In_reads_( SYMCRYPT_AES_BLOCK_SIZE ) PCBYTE pbTweak,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData ) = 0;
// Return zero if success, NT status error if not supported.
};
class StreamCipherImplementation: public AlgorithmImplementation
{
public:
StreamCipherImplementation() {};
virtual ~StreamCipherImplementation() {};
private:
StreamCipherImplementation( const StreamCipherImplementation & );
VOID operator=( const StreamCipherImplementation & );
public:
virtual std::set<SIZE_T> getNonceSizes() = 0;
virtual std::set<SIZE_T> getKeySizes() = 0;
virtual NTSTATUS setKey( _In_reads_( cbKey ) PCBYTE pbKey, SIZE_T cbKey ) = 0;
virtual NTSTATUS setNonce( _In_reads_( cbNonce ) PCBYTE pbNonce, SIZE_T cbNonce ) = 0;
virtual BOOL isRandomAccess() = 0;
virtual VOID setOffset( UINT64 offset ) = 0;
virtual VOID encrypt(
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData ) = 0;
};
class RngSp800_90Implementation: public AlgorithmImplementation
{
public:
RngSp800_90Implementation() {};
virtual ~RngSp800_90Implementation() {};
private:
RngSp800_90Implementation( const RngSp800_90Implementation & );
VOID operator=( const RngSp800_90Implementation & );
public:
virtual NTSTATUS instantiate( _In_reads_( cbEntropy ) PCBYTE pbEntropy, SIZE_T cbEntropy ) = 0;
virtual NTSTATUS reseed( _In_reads_( cbEntropy ) PCBYTE pbEntropy, SIZE_T cbEntropy ) = 0;
virtual VOID generate( _Out_writes_( cbData ) PBYTE pbData, SIZE_T cbData ) = 0;
};
//
// KDF implementation
//
typedef enum _KDF_ARGUMENT_TYPE {
KdfArgumentGeneric = 1, // numeric values are used in KAT files, do not change.
KdfArgumentPbkdf2 = 2,
KdfArgumentSp800_108 = 3,
KdfArgumentTlsPrf = 4,
KdfArgumentHkdf = 5,
KdfArgumentSshKdf = 6,
KdfArgumentSrtpKdf = 7,
KdfArgumentSskdf = 8,
} KDF_ARGUMENT_TYPE;
typedef struct _KDF_GENERIC_ARGUMENTS {
PCBYTE pbSelector;
SIZE_T cbSelector;
} KDF_GENERIC_ARGUMENTS;
typedef struct _KDF_PBKDF2_ARGUMENTS {
PCBYTE pbSalt;
SIZE_T cbSalt;
ULONGLONG iterationCnt;
} KDF_PBKDF2_ARGUMENTS;
typedef struct _KDF_SP800_108_ARGUMENTS {
PCBYTE pbLabel;
SIZE_T cbLabel;
PCBYTE pbContext;
SIZE_T cbContext;
} KDF_SP800_108_ARGUMENTS;
typedef struct _KDF_TLSPRF_ARGUMENTS {
PCBYTE pbLabel;
SIZE_T cbLabel;
PCBYTE pbSeed;
SIZE_T cbSeed;
} KDF_TLSPRF_ARGUMENTS;
typedef struct _KDF_HKDF_ARGUMENTS {
PCBYTE pbSalt;
SIZE_T cbSalt;
PCBYTE pbInfo;
SIZE_T cbInfo;
} KDF_HKDF_ARGUMENTS;
typedef struct _KDF_SSHKDF_ARGUMENTS {
PCSTR hashName;
PCBYTE pbHashValue;
SIZE_T cbHashValue;
PCBYTE pbSessionId;
SIZE_T cbSessionId;
BYTE label;
} KDF_SSHKDF_ARGUMENTS;
typedef struct _KDF_SRTPKDF_ARGUMENTS {
PCBYTE pbSalt;
SIZE_T cbSalt;
UINT32 uKeyDerivationRate;
UINT64 uIndex;
UINT32 uIndexWidth;
BYTE label;
} KDF_SRTPKDF_ARGUMENTS;
typedef struct _KDF_SSKDF_ARGUMENTS {
PCBYTE pbSalt;
SIZE_T cbSalt;
PCBYTE pbInfo;
SIZE_T cbInfo;
} KDF_SSKDF_ARGUMENTS;
typedef struct _KDF_ARGUMENTS {
KDF_ARGUMENT_TYPE argType;
union {
KDF_GENERIC_ARGUMENTS uGeneric;
KDF_PBKDF2_ARGUMENTS uPbkdf2;
KDF_SP800_108_ARGUMENTS uSp800_108;
KDF_TLSPRF_ARGUMENTS uTlsPrf;
KDF_HKDF_ARGUMENTS uHkdf;
KDF_SSHKDF_ARGUMENTS uSshKdf;
KDF_SRTPKDF_ARGUMENTS uSrtpKdf;
KDF_SSKDF_ARGUMENTS uSskdf;
};
} KDF_ARGUMENTS, *PKDF_ARGUMENTS;
typedef const KDF_ARGUMENTS *PCKDF_ARGUMENTS;
class KdfImplementation: public AlgorithmImplementation
{
public:
KdfImplementation() {};
virtual ~KdfImplementation() {};
private:
KdfImplementation( const KdfImplementation & );
VOID operator=( const KdfImplementation & );
public:
virtual VOID derive(
_In_reads_( cbKey ) PCBYTE pbKey,
SIZE_T cbKey,
_In_ PKDF_ARGUMENTS args,
_Out_writes_( cbDst ) PBYTE pbDst,
SIZE_T cbDst ) = 0;
};
class TlsCbcHmacImplementation: public AlgorithmImplementation
{
public:
TlsCbcHmacImplementation() {};
~TlsCbcHmacImplementation() {};
private:
TlsCbcHmacImplementation( const TlsCbcHmacImplementation & );
VOID operator=( const TlsCbcHmacImplementation & );
public:
virtual NTSTATUS verify(
_In_reads_( cbKey ) PCBYTE pbKey,
SIZE_T cbKey,
_In_reads_( cbHeader ) PCBYTE pbHeader,
SIZE_T cbHeader,
_In_reads_( cbData ) PCBYTE pbData,
SIZE_T cbData ) = 0;
// Verify a TLS 1.2 CBC HMAC padded record in constant time
};
// ArithImplementation class is only used for performance measurement
class ArithImplementation: public AlgorithmImplementation
{
public:
ArithImplementation() {};
virtual ~ArithImplementation() {};
private:
ArithImplementation( const ArithImplementation & );
VOID operator=( const ArithImplementation & );
public:
};
// We need an implementation-independent way to store RSA keys
// As RSA key gen is so expensive, we generate a bunch of keys up front and use
// them for all tests.
#define RSAKEY_MAXKEYSIZE (1024) // 8192 bits = 1024 bytes
typedef struct _RSAKEY_TESTBLOB {
UINT32 nBitsModulus;
UINT64 u64PubExp;
UINT32 cbModulus;
UINT32 cbPrime1;
UINT32 cbPrime2;
BYTE abModulus[RSAKEY_MAXKEYSIZE];
BYTE abPrime1[RSAKEY_MAXKEYSIZE];
BYTE abPrime2[RSAKEY_MAXKEYSIZE];
// Only set in OpenSSL implementation right now.
BYTE abPrivateExp[RSAKEY_MAXKEYSIZE];
// And some fields to make debugging easier
const char * pcstrSource; // Where did this key come from
INT64 u64Line; // line # of test vector file (if applicable)
} RSAKEY_TESTBLOB, *PRSAKEY_TESTBLOB;
typedef const RSAKEY_TESTBLOB * PCRSAKEY_TESTBLOB;
class RsaSignImplementation: public AlgorithmImplementation
{
public:
RsaSignImplementation() {};
virtual ~RsaSignImplementation() {};
private:
RsaSignImplementation( const RsaSignImplementation & );
VOID operator=( const RsaSignImplementation & );
public:
virtual NTSTATUS setKey( PCRSAKEY_TESTBLOB pcKeyBlob ) = 0; // Returns an error if this key can't be handled.
// This is the abstraction that covers both PKCS1 and PSS. Both take a hash alg as parameter.
// We also add a salt size used for PSS.
virtual NTSTATUS sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
PCSTR pcstrHashAlgName,
UINT32 u32Other,
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig ) = 0; // cbSig == cbModulus of key
virtual NTSTATUS verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig,
PCSTR pcstrHashAlgName,
UINT32 u32Other ) = 0;
};
class RsaEncImplementation: public AlgorithmImplementation
{
public:
RsaEncImplementation() {};
virtual ~RsaEncImplementation() {};
private:
RsaEncImplementation( const RsaEncImplementation & );
VOID operator=( const RsaEncImplementation & );
public:
virtual NTSTATUS setKey( PCRSAKEY_TESTBLOB pcKeyBlob ) = 0; // Returns an error if this key can't be handled.
// This is the abstraction that covers RAW, PKCS1 and OAEP.
virtual NTSTATUS encrypt(
_In_reads_( cbMsg ) PCBYTE pbMsg,
SIZE_T cbMsg,
PCSTR pcstrHashAlgName,
PCBYTE pbLabel,
SIZE_T cbLabel,
_Out_writes_( cbCiphertext ) PBYTE pbCiphertext,
SIZE_T cbCiphertext ) = 0; // == cbModulus of key
virtual NTSTATUS decrypt(
_In_reads_( cbCiphertext ) PCBYTE pbCiphertext,
SIZE_T cbCiphertext,
PCSTR pcstrHashAlgName,
PCBYTE pbLabel,
SIZE_T cbLabel,
_Out_writes_to_(cbMsg,*pcbMsg) PBYTE pbMsg,
SIZE_T cbMsg,
SIZE_T *pcbMsg ) = 0;
};
#define DLKEY_MAXKEYSIZE (1024) // 8192 bits = 1024 bytes. Generating larger groups is too slow for testing
typedef struct _DLGROUP_TESTBLOB {
UINT32 nBitsP; // P = field prime, Q = subgroup order, G = generator
UINT32 cbPrimeP; //
UINT32 cbPrimeQ; // can be 0 if group order is not known
SYMCRYPT_DLGROUP_FIPS fipsStandard; // Which FIPS standard was used to generate this group
PCSYMCRYPT_HASH pHashAlgorithm; // Used for FIPS group generation
UINT32 cbSeed; // FIPS group generation seed
UINT32 genCounter; // FIPS group generation counter
BOOLEAN fHasPrimeQ; // Flag that specifies whether the object has a Q parameter
BOOLEAN isSafePrimeGroup; // Boolean indicating if this is a Safe Prime group
PCSTR pcstrHashAlgName; // Used for FIPS group generation in multi-implementation tests
BYTE abPrimeP[DLKEY_MAXKEYSIZE]; // cbPrimeP bytes
BYTE abPrimeQ[DLKEY_MAXKEYSIZE]; // cbPrimeQ bytes (optional)
BYTE abGenG[DLKEY_MAXKEYSIZE]; // cbPrimeP bytes
BYTE abSeed[DLKEY_MAXKEYSIZE]; // cbSeed bytes, cbSeed = 0 or cbSeed = cbPrimeQ
} DLGROUP_TESTBLOB, *PDLGROUP_TESTBLOB;
typedef const DLGROUP_TESTBLOB * PCDLGROUP_TESTBLOB;
typedef struct _DLKEY_TESTBLOB {
PCDLGROUP_TESTBLOB pGroup;
UINT32 nBitsPriv; // Non-zero value indicates Dlkey in DH safe-prime group with
// specified private key length
UINT32 cbPrivKey; //
BYTE abPubKey[DLKEY_MAXKEYSIZE]; // cbPrimeP bytes
BYTE abPrivKey[DLKEY_MAXKEYSIZE]; // cbPrivKey bytes
BOOL fPrivateModP; // private key in range [1,P-2] - not [1,Q-1]
} DLKEY_TESTBLOB, *PDLKEY_TESTBLOB;
typedef const DLKEY_TESTBLOB * PCDLKEY_TESTBLOB;
class DhImplementation: public AlgorithmImplementation
{
public:
DhImplementation() {};
virtual ~DhImplementation() {};
private:
DhImplementation( const DhImplementation & );
VOID operator=( const DhImplementation & );
public:
virtual NTSTATUS setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob ) = 0; // Returns an error if this key can't be handled.
virtual NTSTATUS sharedSecret(
_In_ PCDLKEY_TESTBLOB pcPubkey, // Must be on same group object
_Out_writes_( cbSecret ) PBYTE pbSecret,
SIZE_T cbSecret ) = 0;
};
class DsaImplementation: public AlgorithmImplementation
{
public:
DsaImplementation() {};
virtual ~DsaImplementation() {};
private:
DsaImplementation( const DsaImplementation & );
VOID operator=( const DsaImplementation & );
public:
virtual NTSTATUS setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob ) = 0; // Returns an error if this key can't be handled.
virtual NTSTATUS sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash, // Can be any size, but often = size of Q
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig ) = 0; // cbSig == 2 * cbPrimeQ of group
virtual NTSTATUS verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig ) = 0;
};
// RsaImplementation class is only used for performance measurements of RSA
/*
class RsaImplementation: public AlgorithmImplementation
{
public:
RsaImplementation() {};
virtual ~RsaImplementation() {};
private:
RsaImplementation( const RsaImplementation & );
VOID operator=( const RsaImplementation & );
public:
};
*/
// DlImplementation class is only used for performance measurements of Discrete Log group algorithms
class DlImplementation: public AlgorithmImplementation
{
public:
DlImplementation() {};
virtual ~DlImplementation() {};
private:
DlImplementation( const DlImplementation & );
VOID operator=( const DlImplementation & );
public:
};
// EccImplementation class is only used for performance measurements of elliptic curve cryptography
class EccImplementation: public AlgorithmImplementation
{
public:
EccImplementation() {};
virtual ~EccImplementation() {};
private:
EccImplementation( const EccImplementation & );
VOID operator=( const EccImplementation & );
public:
};
//////////////////////////////////////////////////////////////////////////////////
// Template classes for actual concrete implementations
//
//
// A template class to store the state of a hash implementation in.
//
template< class Implementation, class Algorithm> class HashImpState;
//
// A template class for the actual hash algorithm implementations
//
template< class Implementation, class Algorithm >
class HashImp: public HashImplementation
{
public:
HashImp();
virtual ~HashImp();
private:
HashImp( const HashImp & );
VOID operator=( const HashImp & );
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual SIZE_T resultLen();
virtual SIZE_T inputBlockLen();
virtual void init();
virtual void append( _In_reads_( cbData ) PCBYTE pbData, SIZE_T cbData );
virtual void result( _Out_writes_( cbResult ) PBYTE pbResult, SIZE_T cbResult );
virtual VOID hash(
_In_reads_( cbData ) PCBYTE pbData,
SIZE_T cbData,
_Out_writes_( cbResult ) PBYTE pbResult,
SIZE_T cbResult );
virtual NTSTATUS initWithLongMessage( ULONGLONG nBytes );
virtual NTSTATUS exportSymCryptFormat(
_Out_writes_bytes_to_( cbResultBufferSize, *pcbResult ) PBYTE pbResult,
_In_ SIZE_T cbResultBufferSize,
_Out_ SIZE_T *pcbResult );
HashImpState<Implementation,Algorithm> state;
};
//
// A template class to store the state of a hash implementation in.
//
template< class Implementation, class Algorithm> class ParallelHashImpState;
//
// A template class for the actual hash algorithm implementations
//
template< class Implementation, class Algorithm >
class ParallelHashImp: public ParallelHashImplementation
{
public:
ParallelHashImp();
virtual ~ParallelHashImp();
private:
ParallelHashImp( const ParallelHashImp & );
VOID operator=( const ParallelHashImp & );
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual PCSYMCRYPT_HASH SymCryptHash();
virtual SIZE_T resultLen();
virtual SIZE_T inputBlockLen();
virtual VOID init( SIZE_T nHashes );
virtual VOID process(
_In_reads_( nOperations ) BCRYPT_MULTI_HASH_OPERATION * pOperations,
SIZE_T nOperations );
virtual NTSTATUS initWithLongMessage( ULONGLONG nBytes );
ParallelHashImpState<Implementation,Algorithm> state;
};
//
// A template class to store the state of a XOF implementation in.
//
template< class Implementation, class Algorithm> class XofImpState;
//
// A template class for the actual XOF implementations
//
template< class Implementation, class Algorithm >
class XofImp: public XofImplementation
{
public:
XofImp();
virtual ~XofImp();
private:
XofImp( const XofImp & );
VOID operator=( const XofImp & );
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual SIZE_T inputBlockLen();
virtual void init();
virtual void append( _In_reads_( cbData ) PCBYTE pbData, SIZE_T cbData );
virtual void extract( _Out_writes_( cbResult ) PBYTE pbResult, SIZE_T cbResult, BOOLEAN bWipe);
virtual void result( _Out_writes_( cbResult ) PBYTE pbResult, SIZE_T cbResult );
virtual VOID xof(
_In_reads_( cbData ) PCBYTE pbData,
SIZE_T cbData,
_Out_writes_( cbResult ) PBYTE pbResult,
SIZE_T cbResult );
XofImpState<Implementation,Algorithm> state;
};
//
// A template class to store the state of a customizable XOF implementation in.
//
template< class Implementation, class Algorithm> class CustomizableXofImpState;
//
// A template class for the actual XOF implementations
//
template< class Implementation, class Algorithm >
class CustomizableXofImp : public CustomizableXofImplementation
{
public:
CustomizableXofImp();
virtual ~CustomizableXofImp();
private:
CustomizableXofImp(const CustomizableXofImp&);
VOID operator=(const CustomizableXofImp&);
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual SIZE_T inputBlockLen();
virtual void init(
_In_reads_( cbNstr ) PCBYTE pbNstr,
SIZE_T cbNstr,
_In_reads_( cbSstr ) PCBYTE pbSstr,
SIZE_T cbSstr);
virtual void append(_In_reads_(cbData) PCBYTE pbData, SIZE_T cbData);
virtual void extract(_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult, BOOLEAN bWipe);
virtual void result(_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult);
virtual VOID xof(
_In_reads_( cbNstr ) PCBYTE pbNstr,
SIZE_T cbNstr,
_In_reads_( cbSstr ) PCBYTE pbSstr,
SIZE_T cbSstr,
_In_reads_( cbData ) PCBYTE pbData,
SIZE_T cbData,
_Out_writes_( cbResult ) PBYTE pbResult,
SIZE_T cbResult );
CustomizableXofImpState<Implementation, Algorithm> state;
};
//
// Template class to store the state of a MAC implementation
//
template< class Implementation, class Algorithm> class MacImpState;
//
// Template class for the actual MAC implementations
//
template< class Implementation, class Algorithm >
class MacImp: public MacImplementation
{
public:
MacImp();
virtual ~MacImp();
private:
MacImp( const MacImp & );
VOID operator=( const MacImp & );
public:
static const String s_algName;
static const String s_modeName;
static const String s_impName;
virtual SIZE_T resultLen();
virtual SIZE_T inputBlockLen();
virtual NTSTATUS init( _In_reads_( cbKey ) PCBYTE pbKey, SIZE_T cbKey );
virtual VOID append( _In_reads_( cbData ) PCBYTE pbData, SIZE_T cbData );
virtual VOID result( _Out_writes_( cbResult ) PBYTE pbResult, SIZE_T cbResult );
virtual NTSTATUS mac(
_In_reads_( cbKey ) PCBYTE pbKey,
SIZE_T cbKey,
_In_reads_( cbData ) PCBYTE pbData,
SIZE_T cbData,
_Out_writes_( cbResult ) PBYTE pbResult,
SIZE_T cbResult );
MacImpState<Implementation,Algorithm> state;
};
//
// A template class to store the state of a KMAC implementation in.
//
template< class Implementation, class Algorithm> class KmacImpState;
//
// Template class for the actual MAC implementations
//
template< class Implementation, class Algorithm >
class KmacImp : public KmacImplementation
{
public:
KmacImp();
virtual ~KmacImp();
private:
KmacImp(const KmacImp&);
VOID operator=(const KmacImp&);
public:
static const String s_algName;
static const String s_modeName;
static const String s_impName;
virtual SIZE_T inputBlockLen();
virtual VOID init(
_In_reads_(cbCustomizationStr) PCBYTE pbCustomizationStr,
SIZE_T cbCustomizationStr,
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey);
virtual VOID append(_In_reads_(cbData) PCBYTE pbData, SIZE_T cbData);
virtual VOID result(_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult);
virtual VOID extract(_Out_writes_(cbResult) PBYTE pbResult, SIZE_T cbResult, BOOLEAN bWipe);
virtual VOID mac(
_In_reads_(cbCustomizationStr) PCBYTE pbCustomizationStr,
SIZE_T cbCustomizationStr,
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey,
_In_reads_(cbData) PCBYTE pbData,
SIZE_T cbData,
_Out_writes_(cbResult) PBYTE pbResult,
SIZE_T cbResult);
virtual VOID xof(
_In_reads_(cbCustomizationStr) PCBYTE pbCustomizationStr,
SIZE_T cbCustomizationStr,
_In_reads_(cbKey) PCBYTE pbKey,
SIZE_T cbKey,
_In_reads_(cbData) PCBYTE pbData,
SIZE_T cbData,
_Out_writes_(cbResult) PBYTE pbResult,
SIZE_T cbResult);
KmacImpState<Implementation, Algorithm> state;
};
template< class Implementation, class Algorithm, class Mode > class BlockCipherImpState;
template< class Implementation, class Algorithm, class Mode >
class BlockCipherImp: public BlockCipherImplementation
{
public:
BlockCipherImp();
virtual ~BlockCipherImp();
private:
BlockCipherImp( const BlockCipherImp & );
VOID operator=( const BlockCipherImp & );
public:
static const String s_algName;
static const String s_modeName;
static const String s_impName;
virtual SIZE_T msgBlockLen(); // block length of mode (msg must be multiple of this)
virtual SIZE_T chainBlockLen(); // length of chaining field
virtual SIZE_T coreBlockLen(); // block length of underlying cipher
virtual NTSTATUS setKey( _In_reads_( cbKey ) PCBYTE pbKey, SIZE_T cbKey );
virtual VOID encrypt(
_Inout_updates_opt_( cbChain ) PBYTE pbChain,
SIZE_T cbChain,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData );
virtual VOID decrypt(
_Inout_updates_opt_( cbChain ) PBYTE pbChain,
SIZE_T cbChain,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData );
BlockCipherImpState< Implementation, Algorithm, Mode > state;
};
template< class Implementation, class Algorithm > class XtsImpState;
template< class Implementation, class Algorithm >
class XtsImp: public XtsImplementation
{
public:
XtsImp();
virtual ~XtsImp();
private:
XtsImp( const XtsImp & );
VOID operator=( const XtsImp & );
public:
static const String s_algName;
static const String s_modeName;
static const String s_impName;
virtual NTSTATUS setKey( PCBYTE pbKey, SIZE_T cbKey, UINT32 flags );
virtual NTSTATUS encrypt(
SIZE_T cbDataUnit,
ULONGLONG tweak,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData );
// Return zero if success, NT status error if not supported.
virtual NTSTATUS decrypt(
SIZE_T cbDataUnit,
ULONGLONG tweak,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData );
// Return zero if success, NT status error if not supported.
virtual NTSTATUS encryptWith128bTweak(
SIZE_T cbDataUnit,
_In_reads_( SYMCRYPT_AES_BLOCK_SIZE ) PCBYTE pbTweak,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData );
// Return zero if success, NT status error if not supported.
virtual NTSTATUS decryptWith128bTweak(
SIZE_T cbDataUnit,
_In_reads_( SYMCRYPT_AES_BLOCK_SIZE ) PCBYTE pbTweak,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData );
// Return zero if success, NT status error if not supported.
XtsImpState< Implementation, Algorithm > state;
};
template< class Implementation, class Algorithm, class Mode >
SIZE_T BlockCipherImp<Implementation, Algorithm, Mode>::chainBlockLen()
{
if( (Mode::flags & MODE_FLAG_CHAIN) == 0 )
{
return 0;
}
return coreBlockLen();
}
template< class Implementation, class Algorithm, class Mode >
SIZE_T BlockCipherImp<Implementation, Algorithm, Mode>::msgBlockLen()
{
if( (Mode::flags & MODE_FLAG_CFB) != 0 )
{
return g_modeCfbShiftParam;
}
return coreBlockLen();
}
template< class Implementation, class Algorithm, class Mode> class AuthEncImpState;
template< class Implementation, class Algorithm, class Mode >
class AuthEncImp: public AuthEncImplementation
{
public:
AuthEncImp();
virtual ~AuthEncImp();
PVOID operator new( size_t size )
{
return std::malloc( size );
}
VOID operator delete( PVOID p )
{
std::free( p );
}
private:
AuthEncImp( const AuthEncImp & );
VOID operator=( const AuthEncImp & );
public:
static const String s_algName;
static const String s_modeName;
static const String s_impName;
virtual std::set<SIZE_T> getNonceSizes();
virtual std::set<SIZE_T> getTagSizes();
virtual std::set<SIZE_T> getKeySizes();
virtual NTSTATUS setKey( PCBYTE pbKey, SIZE_T cbKey );
virtual VOID setTotalCbData( SIZE_T cbData );
virtual NTSTATUS encrypt(
_In_reads_( cbNonce ) PCBYTE pbNonce,
SIZE_T cbNonce,
_In_reads_( cbAuthData ) PCBYTE pbAuthData,
SIZE_T cbAuthData,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData,
_Out_writes_( cbTag ) PBYTE pbTag,
SIZE_T cbTag,
ULONG flags );
// returns an error only if the request is not supported; only allowed for partial requests.
virtual NTSTATUS decrypt(
_In_reads_( cbNonce ) PCBYTE pbNonce,
SIZE_T cbNonce,
_In_reads_( cbAuthData ) PCBYTE pbAuthData,
SIZE_T cbAuthData,
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData,
_In_reads_( cbTag ) PCBYTE pbTag,
SIZE_T cbTag,
ULONG flags );
// returns STATUS_AUTH_TAG_MISMATCH if the tag is wrong.
// returns STATUS_NOT_SUPPORTED if the request is not supported (only for partial requests)
AuthEncImpState< Implementation, Algorithm, Mode > state;
};
template< class Implementation, class Algorithm> class StreamCipherImpState;
template< class Implementation, class Algorithm>
class StreamCipherImp: public StreamCipherImplementation
{
public:
StreamCipherImp();
virtual ~StreamCipherImp();
private:
StreamCipherImp( const StreamCipherImp & );
VOID operator=( const StreamCipherImp & );
public:
static const String s_impName;
static const String s_modeName;
static const String s_algName;
static const BOOL s_isRandomAccess;
virtual std::set<SIZE_T> getNonceSizes();
virtual std::set<SIZE_T> getKeySizes();
virtual NTSTATUS setKey( _In_reads_( cbKey ) PCBYTE pbKey, SIZE_T cbKey );
virtual NTSTATUS setNonce( _In_reads_( cbNonce ) PCBYTE pbNonce, SIZE_T cbNonce );
virtual BOOL isRandomAccess() { return s_isRandomAccess; };
virtual VOID setOffset( UINT64 offset );
virtual VOID encrypt(
_In_reads_( cbData ) PCBYTE pbSrc,
_Out_writes_( cbData ) PBYTE pbDst,
SIZE_T cbData );
StreamCipherImpState< Implementation, Algorithm> state;
};
template< class Implementation, class Algorithm> class RngSp800_90ImpState;
template< class Implementation, class Algorithm>
class RngSp800_90Imp: public RngSp800_90Implementation
{
public:
RngSp800_90Imp();
virtual ~RngSp800_90Imp();
private:
RngSp800_90Imp( const RngSp800_90Imp & );
VOID operator=( const RngSp800_90Imp & );
public:
static const String s_impName;
static const String s_modeName;
static const String s_algName;
virtual NTSTATUS instantiate( _In_reads_( cbEntropy ) PCBYTE pbEntropy, SIZE_T cbEntropy ) ;
virtual NTSTATUS reseed( _In_reads_( cbEntropy ) PCBYTE pbEntropy, SIZE_T cbEntropy );
virtual VOID generate( _Out_writes_( cbData ) PBYTE pbData, SIZE_T cbData );
RngSp800_90ImpState< Implementation, Algorithm> state;
};
template< class Implementation, class Algorithm, class BaseAlg > class KdfImpState;
template< class Implementation, class Algorithm, class BaseAlg >
class KdfImp: public KdfImplementation
{
public:
KdfImp();
virtual ~KdfImp();
private:
KdfImp( const KdfImp & );
VOID operator=( const KdfImp & );
public:
static const String s_impName;
static const String s_modeName;
static const String s_algName;
virtual VOID derive(
_In_reads_( cbKey ) PCBYTE pbKey,
SIZE_T cbKey,
_In_ PKDF_ARGUMENTS args,
_Out_writes_( cbDst ) PBYTE pbDst,
SIZE_T cbDst );
KdfImpState<Implementation,Algorithm,BaseAlg> state;
};
template< class Implementation, class Algorithm >
class TlsCbcHmacImp: public TlsCbcHmacImplementation
{
public:
TlsCbcHmacImp();
virtual ~TlsCbcHmacImp();
private:
TlsCbcHmacImp( const TlsCbcHmacImp & );
VOID operator=( const TlsCbcHmacImp & );
public:
static const String s_algName;
static const String s_modeName;
static const String s_impName;
virtual NTSTATUS verify(
_In_reads_( cbKey ) PCBYTE pbKey,
SIZE_T cbKey,
_In_reads_( cbHeader ) PCBYTE pbHeader,
SIZE_T cbHeader,
_In_reads_( cbData ) PCBYTE pbData,
SIZE_T cbData );
};
template< class Implementation, class Algorithm>
class ArithImp: public ArithImplementation
{
public:
ArithImp();
virtual ~ArithImp();
private:
ArithImp( const ArithImp & );
VOID operator=( const ArithImp & );
public:
static const String s_impName;
static const String s_modeName;
static const String s_algName;
};
/*
template< class Implementation, class Algorithm>
class RsaImp: public RsaImplementation
{
public:
RsaImp();
virtual ~RsaImp();
private:
RsaImp( const RsaImp & );
VOID operator=( const RsaImp & );
public:
static const String s_impName;
static const String s_modeName;
static const String s_algName;
};
*/
template< class Implementation, class Algorithm>
class DlImp: public DlImplementation
{
public:
DlImp();
virtual ~DlImp();
private:
DlImp( const DlImp & );
VOID operator=( const DlImp & );
public:
static const String s_impName;
static const String s_modeName;
static const String s_algName;
};
template< class Implementation, class Algorithm > class RsaSignImpState;
template< class Implementation, class Algorithm>
class RsaSignImp: public RsaSignImplementation
{
public:
RsaSignImp();
virtual ~RsaSignImp();
private:
RsaSignImp( const RsaSignImp & );
VOID operator=( const RsaSignImp & );
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual NTSTATUS setKey( PCRSAKEY_TESTBLOB pcKeyBlob );
virtual NTSTATUS sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
PCSTR pcstrHashAlgName,
UINT32 u32Other,
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig );
virtual NTSTATUS verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig,
PCSTR pcstrHashAlgName,
UINT32 u32Other );
RsaSignImpState<Implementation,Algorithm> state;
};
template< class Implementation, class Algorithm > class RsaEncImpState;
template< class Implementation, class Algorithm>
class RsaEncImp: public RsaEncImplementation
{
public:
RsaEncImp();
virtual ~RsaEncImp();
private:
RsaEncImp( const RsaEncImp & );
VOID operator=( const RsaEncImp & );
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual NTSTATUS setKey( PCRSAKEY_TESTBLOB pcKeyBlob );
virtual NTSTATUS encrypt(
_In_reads_( cbMsg ) PCBYTE pbMsg,
SIZE_T cbMsg,
PCSTR pcstrHashAlgName,
PCBYTE pbLabel,
SIZE_T cbLabel,
_Out_writes_( cbCiphertext ) PBYTE pbCiphertext,
SIZE_T cbCiphertext ); // == cbModulus of key
virtual NTSTATUS decrypt(
_In_reads_( cbCiphertext ) PCBYTE pbCiphertext,
SIZE_T cbCiphertext,
PCSTR pcstrHashAlgName,
PCBYTE pbLabel,
SIZE_T cbLabel,
_Out_writes_to_(cbMsg,*pcbMsg) PBYTE pbMsg,
SIZE_T cbMsg,
SIZE_T *pcbMsg );
RsaEncImpState<Implementation,Algorithm> state;
};
template< class Implementation, class Algorithm > class DhImpState;
template< class Implementation, class Algorithm>
class DhImp: public DhImplementation
{
public:
DhImp();
virtual ~DhImp();
private:
DhImp( const DhImp & );
VOID operator=( const DhImp & );
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual NTSTATUS setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob );
virtual NTSTATUS sharedSecret(
_In_ PCDLKEY_TESTBLOB pcPubkey,
_Out_writes_( cbSecret ) PBYTE pbSecret,
SIZE_T cbSecret );
DhImpState<Implementation,Algorithm> state;
};
template< class Implementation, class Algorithm > class DsaImpState;
template< class Implementation, class Algorithm>
class DsaImp: public DsaImplementation
{
public:
DsaImp();
virtual ~DsaImp();
private:
DsaImp( const DsaImp & );
VOID operator=( const DsaImp & );
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual NTSTATUS setKey(
_In_ PCDLKEY_TESTBLOB pcKeyBlob ); // Returns an error if this key can't be handled.
virtual NTSTATUS sign(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash, // Can be any size, but often = size of Q
_Out_writes_( cbSig ) PBYTE pbSig,
SIZE_T cbSig ); // cbSig == cbModulus of group
virtual NTSTATUS verify(
_In_reads_( cbHash) PCBYTE pbHash,
SIZE_T cbHash,
_In_reads_( cbSig ) PCBYTE pbSig,
SIZE_T cbSig );
DsaImpState<Implementation,Algorithm> state;
};
template< class Implementation, class Algorithm>
class EccImp: public EccImplementation
{
public:
EccImp();
virtual ~EccImp();
private:
EccImp( const EccImp & );
VOID operator=( const EccImp & );
public:
static const String s_impName;
static const String s_modeName;
static const String s_algName;
};
class KemImplementation : public AlgorithmImplementation
{
public:
KemImplementation() {};
virtual ~KemImplementation() {};
private:
KemImplementation( const KemImplementation & );
VOID operator=( const KemImplementation & );
public:
virtual NTSTATUS setKeyFromTestBlob(
_In_reads_bytes_( cbTestKeyBlob ) PCBYTE pcbTestKeyBlob,
SIZE_T cbTestKeyBlob,
BOOL canDecapsulate ) = 0;
virtual NTSTATUS getBlobFromKey(
UINT32 blobType,
_Out_writes_bytes_( cbBlob ) PBYTE pbBlob,
SIZE_T cbBlob ) = 0;
virtual NTSTATUS encapsulate(
_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,
SIZE_T cbAgreedSecret,
_Out_writes_bytes_( cbCiphertext ) PBYTE pbCiphertext,
SIZE_T cbCiphertext ) = 0;
virtual NTSTATUS encapsulateEx(
_In_reads_bytes_( cbRandom ) PCBYTE pbRandom,
SIZE_T cbRandom,
_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,
SIZE_T cbAgreedSecret,
_Out_writes_bytes_( cbCiphertext ) PBYTE pbCiphertext,
SIZE_T cbCiphertext ) = 0;
virtual NTSTATUS decapsulate(
_In_reads_bytes_( cbCiphertext ) PCBYTE pbCiphertext,
SIZE_T cbCiphertext,
_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,
SIZE_T cbAgreedSecret ) = 0;
};
// Currently maximum key blob size is ML-KEM1024 decapsulation key blob
#define MAX_MLKEMKEY_BLOB_SIZE (3168)
typedef struct _MLKEMKEY_TESTBLOB
{
SYMCRYPT_MLKEM_PARAMS params; // represents the parameter set of ML-KEM
SYMCRYPT_MLKEMKEY_FORMAT format; // represents the format of the ML-KEM key blob
BYTE abKeyBlob[MAX_MLKEMKEY_BLOB_SIZE]; // byte blob representing an ML-KEM key
SIZE_T cbKeyBlob;
} MLKEMKEY_TESTBLOB, *PMLKEMKEY_TESTBLOB;
typedef const MLKEMKEY_TESTBLOB * PCMLKEMKEY_TESTBLOB;
template< class Implementation, class Algorithm > class KemImpState;
template< class Implementation, class Algorithm >
class KemImp : public KemImplementation
{
public:
KemImp();
virtual ~KemImp();
private:
KemImp( const KemImp & );
VOID operator=( const KemImp & );
public:
static const String s_algName; // Algorithm name
static const String s_modeName;
static const String s_impName; // Implementation name
virtual NTSTATUS setKeyFromTestBlob(
_In_reads_bytes_( cbTestKeyBlob ) PCBYTE pcbTestKeyBlob,
SIZE_T cbTestKeyBlob,
BOOL canDecapsulate );
virtual NTSTATUS getBlobFromKey(
UINT32 blobType,
_Out_writes_bytes_( cbBlob ) PBYTE pbBlob,
SIZE_T cbBlob );
virtual NTSTATUS encapsulate(
_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,
SIZE_T cbAgreedSecret,
_Out_writes_bytes_( cbCiphertext ) PBYTE pbCiphertext,
SIZE_T cbCiphertext );
virtual NTSTATUS encapsulateEx(
_In_reads_bytes_( cbRandom ) PCBYTE pbRandom,
SIZE_T cbRandom,
_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,
SIZE_T cbAgreedSecret,
_Out_writes_bytes_( cbCiphertext ) PBYTE pbCiphertext,
SIZE_T cbCiphertext );
virtual NTSTATUS decapsulate(
_In_reads_bytes_( cbCiphertext ) PCBYTE pbCiphertext,
SIZE_T cbCiphertext,
_Out_writes_bytes_( cbAgreedSecret ) PBYTE pbAgreedSecret,
SIZE_T cbAgreedSecret );
KemImpState<Implementation,Algorithm> state;
};
// Hash-Based Signatures
class HbsImplementation : public AlgorithmImplementation
{
public:
HbsImplementation() {};
virtual ~HbsImplementation() {};
private:
HbsImplementation(const HbsImplementation&);
VOID operator=(const HbsImplementation&);
public:
virtual NTSTATUS setKey(
UINT32 uAlgId,
BOOL fMultitree,
_In_reads_bytes_(cbSrc) PCBYTE pbSrc,
SIZE_T cbSrc,
BOOL fVerify ) = 0;
// Set an XMSS key from algorithm identifier and key blob.
//
// If fVerify is TRUE then this function computes the public root
// from the private key -only if the key is private- and compares
// it to the public root that is in the private key.
virtual NTSTATUS sign(
_In_reads_bytes_(cbMsg) PCBYTE pbMsg,
SIZE_T cbMsg,
_Out_writes_bytes_(cbSignature) PBYTE pbSignature,
SIZE_T cbSignature ) = 0;
// Sign a message using the private key initialized by setKey()
virtual NTSTATUS verify(
_In_reads_bytes_(cbMsg) PCBYTE pbMsg,
SIZE_T cbMsg,
_In_reads_bytes_(cbSignature) PCBYTE pbSignature,
SIZE_T cbSignature ) = 0;
// Verify a signature on a message using the private key initialized
// by setKey()
};
//
// A template class to store the state of an XMSS implementation in.
//
template<class Implementation, class Algorithm> class XmssImpState;
//
// Template class for the actual XMSS implementations
//
template< class Implementation, class Algorithm >
class XmssImp : public HbsImplementation
{
public:
XmssImp();
virtual ~XmssImp();
private:
XmssImp(const XmssImp&);
VOID operator=(const XmssImp&);
public:
virtual NTSTATUS setKey(
UINT32 uAlgId,
BOOL fMultitree,
_In_reads_bytes_(cbSrc) PCBYTE pbSrc,
SIZE_T cbSrc,
BOOL fVerify );
virtual NTSTATUS sign(
_In_reads_bytes_(cbMsg) PCBYTE pbMsg,
SIZE_T cbMsg,
_Out_writes_bytes_(cbSignature) PBYTE pbSignature,
SIZE_T cbSignature ) ;
virtual NTSTATUS verify(
_In_reads_bytes_(cbMsg) PCBYTE pbMsg,
SIZE_T cbMsg,
_In_reads_bytes_(cbSignature) PCBYTE pbSignature,
SIZE_T cbSignature );
static const String s_algName;
static const String s_modeName;
static const String s_impName;
XmssImpState<Implementation, Algorithm> state;
};
//
// The stub classes we use to distinguish our implementations and algorithms contain the
// name of said implementation/algorithm. We use this to auto-define the algorithm name
// and implementation name of the *Imp<imp,alg> classes.
//
template< class Implementation, class Algorithm >
const String HashImp<Implementation,Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm >
const String HashImp<Implementation,Algorithm>::s_modeName;
template< class Implementation, class Algorithm >
const String HashImp<Implementation,Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm >
const String ParallelHashImp<Implementation,Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm >
const String ParallelHashImp<Implementation,Algorithm>::s_modeName;
template< class Implementation, class Algorithm >
const String ParallelHashImp<Implementation,Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm >
const String XofImp<Implementation,Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm >
const String XofImp<Implementation,Algorithm>::s_modeName;
template< class Implementation, class Algorithm >
const String XofImp<Implementation,Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm >
const String CustomizableXofImp<Implementation,Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm >
const String CustomizableXofImp<Implementation,Algorithm>::s_modeName;
template< class Implementation, class Algorithm >
const String CustomizableXofImp<Implementation,Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm >
const String KmacImp<Implementation,Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm >
const String KmacImp<Implementation,Algorithm>::s_modeName;
template< class Implementation, class Algorithm >
const String KmacImp<Implementation,Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm >
const String MacImp<Implementation,Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm >
const String MacImp<Implementation,Algorithm>::s_modeName;
template< class Implementation, class Algorithm >
const String MacImp<Implementation,Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm, class Mode >
const String BlockCipherImp<Implementation,Algorithm,Mode>::s_algName = Algorithm::name ;
template< class Implementation, class Algorithm, class Mode >
const String BlockCipherImp<Implementation,Algorithm,Mode>::s_modeName = Mode::name ;
template< class Implementation, class Algorithm, class Mode >
const String BlockCipherImp<Implementation,Algorithm,Mode>::s_impName = Implementation::name;
template< class Implementation, class Algorithm, class Mode >
const String AuthEncImp<Implementation, Algorithm, Mode>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm, class Mode >
const String AuthEncImp<Implementation,Algorithm,Mode>::s_modeName = Mode::name ;
template< class Implementation, class Algorithm, class Mode >
const String AuthEncImp<Implementation,Algorithm,Mode>::s_impName = Implementation::name;
template< class Implementation, class Algorithm>
const String StreamCipherImp<Implementation,Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm>
const String StreamCipherImp<Implementation,Algorithm>::s_modeName;
template< class Implementation, class Algorithm>
const String StreamCipherImp<Implementation,Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm>
const BOOL StreamCipherImp<Implementation,Algorithm>::s_isRandomAccess = Algorithm::isRandomAccess;
template< class Implementation, class Algorithm>
const String RngSp800_90Imp<Implementation,Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm>
const String RngSp800_90Imp<Implementation,Algorithm>::s_modeName;
template< class Implementation, class Algorithm>
const String RngSp800_90Imp<Implementation,Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm, class BaseAlg >
const String KdfImp<Implementation,Algorithm,BaseAlg>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm, class BaseAlg >
const String KdfImp<Implementation,Algorithm,BaseAlg>::s_modeName = BaseAlg::name;
template< class Implementation, class Algorithm, class BaseAlg >
const String KdfImp<Implementation,Algorithm,BaseAlg>::s_impName = Implementation::name;
template< class Implementation, class Algorithm>
const String XtsImp<Implementation, Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm>
const String XtsImp<Implementation, Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm>
const String XtsImp<Implementation, Algorithm>::s_modeName;
template< class Implementation, class Algorithm>
const String TlsCbcHmacImp<Implementation, Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm>
const String TlsCbcHmacImp<Implementation, Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm>
const String TlsCbcHmacImp<Implementation, Algorithm>::s_modeName;
template< class Implementation, class Algorithm>
const String ArithImp<Implementation, Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm>
const String ArithImp<Implementation, Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm>
const String ArithImp<Implementation, Algorithm>::s_modeName;
/*
template< class Implementation, class Algorithm>
const String RsaImp<Implementation, Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm>
const String RsaImp<Implementation, Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm>
const String RsaImp<Implementation, Algorithm>::s_modeName;
*/
template< class Implementation, class Algorithm>
const String DlImp<Implementation, Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm>
const String DlImp<Implementation, Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm>
const String DlImp<Implementation, Algorithm>::s_modeName;
template< class Implementation, class Algorithm>
const String EccImp<Implementation, Algorithm>::s_impName = Implementation::name;
template< class Implementation, class Algorithm>
const String EccImp<Implementation, Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm>
const String EccImp<Implementation, Algorithm>::s_modeName;
template< class Imp, class Alg>
const String RsaSignImp<Imp,Alg>::s_impName = Imp::name;
template< class Imp, class Alg>
const String RsaSignImp<Imp,Alg>::s_algName = Alg::name;
template< class Imp, class Alg>
const String RsaSignImp<Imp,Alg>::s_modeName;
template< class Imp, class Alg>
const String RsaEncImp<Imp,Alg>::s_impName = Imp::name;
template< class Imp, class Alg>
const String RsaEncImp<Imp,Alg>::s_algName = Alg::name;
template< class Imp, class Alg>
const String RsaEncImp<Imp,Alg>::s_modeName;
template< class Imp, class Alg>
const String DhImp<Imp,Alg>::s_impName = Imp::name;
template< class Imp, class Alg>
const String DhImp<Imp,Alg>::s_algName = Alg::name;
template< class Imp, class Alg>
const String DhImp<Imp,Alg>::s_modeName;
template< class Imp, class Alg>
const String DsaImp<Imp,Alg>::s_impName = Imp::name;
template< class Imp, class Alg>
const String DsaImp<Imp,Alg>::s_algName = Alg::name;
template< class Imp, class Alg>
const String DsaImp<Imp,Alg>::s_modeName;
template< class Implementation, class Algorithm >
const String XmssImp<Implementation,Algorithm>::s_algName = Algorithm::name;
template< class Implementation, class Algorithm >
const String XmssImp<Implementation,Algorithm>::s_modeName;
template< class Implementation, class Algorithm >
const String XmssImp<Implementation,Algorithm>::s_impName = Implementation::name;
template< class Imp, class Alg>
const String KemImp<Imp,Alg>::s_impName = Imp::name;
template< class Imp, class Alg>
const String KemImp<Imp,Alg>::s_algName = Alg::name;
template< class Imp, class Alg>
const String KemImp<Imp,Alg>::s_modeName;
//
// Template declaration for performance functions (for those implementations that wish to use them)
//
template< class Implementation, class Algorithm >
VOID algImpKeyPerfFunction( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize );
template< class Implementation, class Algorithm, class Mode >
VOID algImpKeyPerfFunction( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize );
template< class Implementation, class Algorithm >
VOID algImpDataPerfFunction( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize );
template< class Implementation, class Algorithm, class Mode >
VOID algImpDataPerfFunction( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize );
template< class Implementation, class Algorithm >
VOID algImpDecryptPerfFunction( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize );
template< class Implementation, class Algorithm, class Mode >
VOID algImpDecryptPerfFunction( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize );
template< class Implementation, class Algorithm >
VOID algImpCleanPerfFunction( PBYTE buf1, PBYTE buf2, PBYTE buf3 );
template< class Implementation, class Algorithm, class Mode >
VOID algImpCleanPerfFunction( PBYTE buf1, PBYTE buf2, PBYTE buf3 );
;