зеркало из https://github.com/microsoft/SymCrypt.git
Merged PR 10817310: Add XMSS and XMSS^MT implementations
## Description: Adds support for stateful hash-based signatures XMSS and XMSS^MT per RFC 8391 and NIST SP800-208. ## Admin Checklist: - [ ] You have updated documentation in symcrypt.h to reflect any changes in behavior - [ ] You have updated CHANGELOG.md to reflect any changes in behavior - [ ] You have updated symcryptunittest to exercise any new functionality - [ ] If you have introduced any symbols in symcrypt.h you have updated production and test dynamic export symbols (exports.ver / exports.def / symcrypt.src) and tested the updated dynamic modules with symcryptunittest - [ ] If you have introduced functionality that varies based on CPU features, you have manually tested with and without relevant features - [ ] If you have made significant changes to a particular algorithm, you have checked that performance numbers reported by symcryptunittest are in line with expectations - [ ] If you have added new algorithms/modes, you have updated the status indicator text for the associated modules if necessary Related work items: #52453903
This commit is contained in:
Родитель
f89cbf36c3
Коммит
15d0779214
|
@ -5,6 +5,7 @@ prior to the creation of a new release, based on the changes contained in that r
|
|||
|
||||
- Internal self-test changes to support FIPS 140-3 certification
|
||||
- Add SSKDF implementation
|
||||
- Add XMSS and XMSS^MT implementations
|
||||
|
||||
# Version 103.4.3
|
||||
|
||||
|
|
551
inc/symcrypt.h
551
inc/symcrypt.h
|
@ -222,6 +222,8 @@ typedef _Return_type_success_( return == SYMCRYPT_NO_ERROR ) enum {
|
|||
SYMCRYPT_INCOMPATIBLE_FORMAT,
|
||||
SYMCRYPT_VALUE_TOO_LARGE,
|
||||
SYMCRYPT_SESSION_REPLAY_FAILURE,
|
||||
SYMCRYPT_HBS_NO_OTS_KEYS_LEFT,
|
||||
SYMCRYPT_HBS_PUBLIC_ROOT_MISMATCH,
|
||||
} SYMCRYPT_ERROR;
|
||||
|
||||
// SYMCRYPT_ECURVE_TYPE needs to be completely defined before including
|
||||
|
@ -8202,6 +8204,555 @@ SymCryptEcDhSecretAgreementSelftest(void);
|
|||
// with FIPS validation, so most callers should never use this function.
|
||||
//
|
||||
|
||||
//========================================================================
|
||||
//
|
||||
// Stateful Hash-based Signatures
|
||||
//
|
||||
// Hash-based signature schemes are digital signature schemes built out of hash
|
||||
// functions. Stateful hash-based signatures are many-time signature schemes
|
||||
// composed of a one-time-signature (OTS) scheme and a Merkle-tree representing
|
||||
// multiple OTS with a public root value. At each signing operation, one of the
|
||||
// (unused) OTS keys is used to sign the message, and the private key is updated
|
||||
// so that the same OTS is not used again. Because there is a limited number of
|
||||
// OTS keys determined at key generation time, signing cannot be performed after
|
||||
// all OTSs are used. This is an important distinction from other digital signature
|
||||
// schemes such as RSA or ECDSA.
|
||||
//
|
||||
// It is crucial for the security of the *stateful* hash-based signatures that the
|
||||
// same private key state NOT be used more than once to sign messages, otherwise all
|
||||
// security is lost.
|
||||
//
|
||||
|
||||
|
||||
//========================================================================
|
||||
// XMSS API
|
||||
//
|
||||
// XMSS is a stateful hash-based signature scheme specified in RFC 8391. The
|
||||
// multi-tree variant is named XMSS^MT.
|
||||
//
|
||||
// XMSS uses WOTS+ as the one-time-signature (OTS) scheme. Public key consists
|
||||
// of two parts; Merkle-tree hash of OTS public keys called the Root, and a Seed value
|
||||
// used in in hash computations. The private key consists of SK_XMSS which is
|
||||
// used to deterministacally create OTS keys, SK_PRF which is used to generate
|
||||
// the randomizer for hashing, and an integer Idx is used to select the next OTS key
|
||||
// for signing.
|
||||
//
|
||||
|
||||
typedef enum _SYMCRYPT_XMSS_ALGID
|
||||
{
|
||||
// Hash Fn. RFC-8391 SP800-208
|
||||
SYMCRYPT_XMSS_SHA2_10_256 = 0x00000001, // SHA-256 X X
|
||||
SYMCRYPT_XMSS_SHA2_16_256 = 0x00000002, // SHA-256 X X
|
||||
SYMCRYPT_XMSS_SHA2_20_256 = 0x00000003, // SHA-256 X X
|
||||
SYMCRYPT_XMSS_SHA2_10_512 = 0x00000004, // SHA-512 X
|
||||
SYMCRYPT_XMSS_SHA2_16_512 = 0x00000005, // SHA-512 X
|
||||
SYMCRYPT_XMSS_SHA2_20_512 = 0x00000006, // SHA-512 X
|
||||
SYMCRYPT_XMSS_SHAKE_10_256 = 0x00000007, // SHAKE128 X
|
||||
SYMCRYPT_XMSS_SHAKE_16_256 = 0x00000008, // SHAKE128 X
|
||||
SYMCRYPT_XMSS_SHAKE_20_256 = 0x00000009, // SHAKE128 X
|
||||
SYMCRYPT_XMSS_SHAKE_10_512 = 0x0000000A, // SHAKE256 X
|
||||
SYMCRYPT_XMSS_SHAKE_16_512 = 0x0000000B, // SHAKE256 X
|
||||
SYMCRYPT_XMSS_SHAKE_20_512 = 0x0000000C, // SHAKE256 X
|
||||
SYMCRYPT_XMSS_SHA2_10_192 = 0x0000000D, // SHA-256 X
|
||||
SYMCRYPT_XMSS_SHA2_16_192 = 0x0000000E, // SHA-256 X
|
||||
SYMCRYPT_XMSS_SHA2_20_192 = 0x0000000F, // SHA-256 X
|
||||
SYMCRYPT_XMSS_SHAKE256_10_256 = 0x00000010, // SHAKE256 X
|
||||
SYMCRYPT_XMSS_SHAKE256_16_256 = 0x00000011, // SHAKE256 X
|
||||
SYMCRYPT_XMSS_SHAKE256_20_256 = 0x00000012, // SHAKE256 X
|
||||
SYMCRYPT_XMSS_SHAKE256_10_192 = 0x00000013, // SHAKE256 X
|
||||
SYMCRYPT_XMSS_SHAKE256_16_192 = 0x00000014, // SHAKE256 X
|
||||
SYMCRYPT_XMSS_SHAKE256_20_192 = 0x00000015, // SHAKE256 X
|
||||
|
||||
} SYMCRYPT_XMSS_ALGID;
|
||||
|
||||
typedef enum _SYMCRYPT_XMSSMT_ALGID
|
||||
{
|
||||
// Hash Fn. RFC-8391 SP800-208
|
||||
// SHA-256 X X
|
||||
SYMCRYPT_XMSSMT_SHA2_20_2_256 = 0x00000001,
|
||||
SYMCRYPT_XMSSMT_SHA2_20_4_256 = 0x00000002,
|
||||
SYMCRYPT_XMSSMT_SHA2_40_2_256 = 0x00000003,
|
||||
SYMCRYPT_XMSSMT_SHA2_40_4_256 = 0x00000004,
|
||||
SYMCRYPT_XMSSMT_SHA2_40_8_256 = 0x00000005,
|
||||
SYMCRYPT_XMSSMT_SHA2_60_3_256 = 0x00000006,
|
||||
SYMCRYPT_XMSSMT_SHA2_60_6_256 = 0x00000007,
|
||||
SYMCRYPT_XMSSMT_SHA2_60_12_256 = 0x00000008,
|
||||
|
||||
// SHA-512 X
|
||||
SYMCRYPT_XMSSMT_SHA2_20_2_512 = 0x00000009,
|
||||
SYMCRYPT_XMSSMT_SHA2_20_4_512 = 0x0000000A,
|
||||
SYMCRYPT_XMSSMT_SHA2_40_2_512 = 0x0000000B,
|
||||
SYMCRYPT_XMSSMT_SHA2_40_4_512 = 0x0000000C,
|
||||
SYMCRYPT_XMSSMT_SHA2_40_8_512 = 0x0000000D,
|
||||
SYMCRYPT_XMSSMT_SHA2_60_3_512 = 0x0000000E,
|
||||
SYMCRYPT_XMSSMT_SHA2_60_6_512 = 0x0000000F,
|
||||
SYMCRYPT_XMSSMT_SHA2_60_12_512 = 0x00000010,
|
||||
|
||||
// SHAKE128 X
|
||||
SYMCRYPT_XMSSMT_SHAKE_20_2_256 = 0x00000011,
|
||||
SYMCRYPT_XMSSMT_SHAKE_20_4_256 = 0x00000012,
|
||||
SYMCRYPT_XMSSMT_SHAKE_40_2_256 = 0x00000013,
|
||||
SYMCRYPT_XMSSMT_SHAKE_40_4_256 = 0x00000014,
|
||||
SYMCRYPT_XMSSMT_SHAKE_40_8_256 = 0x00000015,
|
||||
SYMCRYPT_XMSSMT_SHAKE_60_3_256 = 0x00000016,
|
||||
SYMCRYPT_XMSSMT_SHAKE_60_6_256 = 0x00000017,
|
||||
SYMCRYPT_XMSSMT_SHAKE_60_12_256 = 0x00000018,
|
||||
|
||||
// SHAKE256 X
|
||||
SYMCRYPT_XMSSMT_SHAKE_20_2_512 = 0x00000019,
|
||||
SYMCRYPT_XMSSMT_SHAKE_20_4_512 = 0x0000001A,
|
||||
SYMCRYPT_XMSSMT_SHAKE_40_2_512 = 0x0000001B,
|
||||
SYMCRYPT_XMSSMT_SHAKE_40_4_512 = 0x0000001C,
|
||||
SYMCRYPT_XMSSMT_SHAKE_40_8_512 = 0x0000001D,
|
||||
SYMCRYPT_XMSSMT_SHAKE_60_3_512 = 0x0000001E,
|
||||
SYMCRYPT_XMSSMT_SHAKE_60_6_512 = 0x0000001F,
|
||||
SYMCRYPT_XMSSMT_SHAKE_60_12_512 = 0x00000020,
|
||||
|
||||
// SHA-256 X
|
||||
SYMCRYPT_XMSSMT_SHA2_20_2_192 = 0x00000021,
|
||||
SYMCRYPT_XMSSMT_SHA2_20_4_192 = 0x00000022,
|
||||
SYMCRYPT_XMSSMT_SHA2_40_2_192 = 0x00000023,
|
||||
SYMCRYPT_XMSSMT_SHA2_40_4_192 = 0x00000024,
|
||||
SYMCRYPT_XMSSMT_SHA2_40_8_192 = 0x00000025,
|
||||
SYMCRYPT_XMSSMT_SHA2_60_3_192 = 0x00000026,
|
||||
SYMCRYPT_XMSSMT_SHA2_60_6_192 = 0x00000027,
|
||||
SYMCRYPT_XMSSMT_SHA2_60_12_192 = 0x00000028,
|
||||
|
||||
// SHAKE256 X
|
||||
SYMCRYPT_XMSSMT_SHAKE256_20_2_256 = 0x00000029,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_20_4_256 = 0x0000002A,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_40_2_256 = 0x0000002B,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_40_4_256 = 0x0000002C,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_40_8_256 = 0x0000002D,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_60_3_256 = 0x0000002E,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_60_6_256 = 0x0000002F,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_60_12_256 = 0x00000030,
|
||||
|
||||
// SHAKE256 X
|
||||
SYMCRYPT_XMSSMT_SHAKE256_20_2_192 = 0x00000031,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_20_4_192 = 0x00000032,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_40_2_192 = 0x00000033,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_40_4_192 = 0x00000034,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_40_8_192 = 0x00000035,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_60_3_192 = 0x00000036,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_60_6_192 = 0x00000037,
|
||||
SYMCRYPT_XMSSMT_SHAKE256_60_12_192 = 0x00000038,
|
||||
|
||||
} SYMCRYPT_XMSSMT_ALGID;
|
||||
|
||||
|
||||
typedef enum _SYMCRYPT_XMSSKEY_TYPE
|
||||
{
|
||||
SYMCRYPT_XMSSKEY_TYPE_NONE = 0,
|
||||
SYMCRYPT_XMSSKEY_TYPE_PUBLIC = 1, // Key object contains only public key
|
||||
SYMCRYPT_XMSSKEY_TYPE_PRIVATE = 2, // Key object contains both public key and private key
|
||||
} SYMCRYPT_XMSSKEY_TYPE;
|
||||
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssParamsFromAlgId(
|
||||
SYMCRYPT_XMSS_ALGID id,
|
||||
_Out_ PSYMCRYPT_XMSS_PARAMS pParams);
|
||||
//
|
||||
// Populate SYMCRYPT_XMSS_PARAMS structure for the specified XMSS algorithm identifier
|
||||
// using the predefined parameter sets from RFC 8391 and NIST SP800-208
|
||||
//
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssMtParamsFromAlgId(
|
||||
SYMCRYPT_XMSSMT_ALGID id,
|
||||
_Out_ PSYMCRYPT_XMSS_PARAMS pParams);
|
||||
//
|
||||
// Populate SYMCRYPT_XMSS_PARAMS structure for the specified XMSS^MT algorithm identifier
|
||||
// using the predefined parameter sets from RFC 8391 and NIST SP800-208
|
||||
//
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssSetParams(
|
||||
_Out_ PSYMCRYPT_XMSS_PARAMS pParams,
|
||||
UINT32 id, // algorithm identifier
|
||||
_In_ PCSYMCRYPT_HASH pHash, // hash algorithm
|
||||
UINT32 cbHashOutput, // hash output size
|
||||
UINT32 nWinternitzWidth, // Winternitz parameter (width of digits)
|
||||
UINT32 nTotalTreeHeight, // total tree height
|
||||
UINT32 nLayers, // number of levels
|
||||
UINT32 cbPrefix // domain separator prefix length
|
||||
);
|
||||
//
|
||||
// Populates SYMCRYPT_XMSS_PARAMS structure by user defined parameters
|
||||
//
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// pParams. Pointer to the structure that will be populated with the
|
||||
// supplied parameters.
|
||||
//
|
||||
// id. Algorithm identifier, will be embedded in key and signature objects.
|
||||
//
|
||||
// pHash. Pointer to a hash object that implements a hash function which
|
||||
// will be used in XMSS/XMSS^MT operations.
|
||||
//
|
||||
// cbHashOutput. Output size of the hash function in bytes. Leading cbHashOutput
|
||||
// bytes are taken as hash output if the hash algorithm's actual output size is larger.
|
||||
//
|
||||
// nWinternitzWidth. Winternitz parameter, width of digits in byte sequences.
|
||||
// See remark below for more explanation.
|
||||
//
|
||||
// nTotalTreeHeight. Height of the XMSS/XMSS^MT tree. In a multi-tree setting,
|
||||
// it is the sum of the tree heights of each layer.
|
||||
//
|
||||
// nLayers. Number of layers. For XMSS nLayers=1, otherwise nLayers > 1. When nLayers > 1,
|
||||
// it must divide nTotalTreeHeight without remainder, so that each layer has height
|
||||
// nTotalTreeHeight/nLayers.
|
||||
//
|
||||
// cbPrefix. Number of bytes in the prefix to the hash inputs used to domain separate
|
||||
// PRF functions.
|
||||
//
|
||||
// Requirements:
|
||||
//
|
||||
// cbHashOutput must be nonzero, must be less than or equal to pHash->resultSize,
|
||||
// and must be less than or equal to SYMCRYPT_HASH_MAX_RESULT_SIZE
|
||||
//
|
||||
// nWinternitzWidth must be one of 1, 2, 4, or 8
|
||||
//
|
||||
// nTotalTreeHeight must be non-zero, it must be less than or equal to 32 for
|
||||
// single-tree (nLayers = 1), and must be less than 64 for multi-tree (nLayers > 1)
|
||||
//
|
||||
// nLayers must be non-zero and must divide nTotalTreeHeight without remainder
|
||||
//
|
||||
// cbPrefix must be non-zero
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// RFC 8391 specifies w as the length of the Winternitz chains. Here,
|
||||
// it is used as the width of the digits in an octet string, i.e.,
|
||||
// base2 logarithm of the chain length, which is similar to its use
|
||||
// in LMS/HSS in RFC 8554.
|
||||
//
|
||||
|
||||
|
||||
#define SYMCRYPT_FLAG_XMSSKEY_VERIFY_ROOT (0x00000001)
|
||||
// Verifies the public root value when importing a private key
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssSizeofKeyBlobFromParams(
|
||||
_In_ PCSYMCRYPT_XMSS_PARAMS pParams,
|
||||
SYMCRYPT_XMSSKEY_TYPE keyType,
|
||||
_Out_ SIZE_T* pcbKey );
|
||||
//
|
||||
// Return the size of an XMSS/XMSS^MT key blob associated with the provided XMSS parameters
|
||||
//
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// pParams. Pointer to an XMSS parameters structure that has been properly
|
||||
// initialized before this call.
|
||||
//
|
||||
// keyType. SYMCRYPT_XMSSKEY_TYPE_PUBLIC (resp. SYMCRYPT_XMSSKEY_TYPE_PRIVATE) to
|
||||
// retrieve the size of the public key (resp. private key).
|
||||
//
|
||||
// pcbKey. Pointer to the variable to store the size of a public/private
|
||||
// key blob associated with the XMSS parameters.
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// Callers may provide a NULL pointer for the size they are not interested to query.
|
||||
//
|
||||
|
||||
PSYMCRYPT_XMSS_KEY
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmsskeyAllocate(
|
||||
_In_ PCSYMCRYPT_XMSS_PARAMS pParams,
|
||||
UINT32 flags );
|
||||
//
|
||||
// Allocate an XMSS/XMSS^MT key object and initialize it
|
||||
//
|
||||
// After this call, the key object does not contain a key yet. It must be
|
||||
// followed by a call to SymCryptXmsskeyGenerate or SymCryptXmsskeySetValue.
|
||||
//
|
||||
// Allowed flags:
|
||||
//
|
||||
// No flags defined for this function
|
||||
//
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmsskeyGenerate(
|
||||
_Inout_ PSYMCRYPT_XMSS_KEY pKey,
|
||||
UINT32 flags );
|
||||
//
|
||||
// Generate a public/private XMSS/XMSS^MT key-pair
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// pKey. Key object to store the public/private key-pair
|
||||
//
|
||||
// flags. No flags defined for this function
|
||||
//
|
||||
// Return values:
|
||||
//
|
||||
// - SYMCRYPT_NO_ERROR
|
||||
// On successfull key generation
|
||||
//
|
||||
// - SYMCRYPT_MEMORY_ALLOCATION_FAILURE
|
||||
// If there is not enough memory to perform key generation
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// - Generates a random private key (SK_XMSS, SK_PRF) and a random
|
||||
// public seed SEED, and computes the public value Root from it.
|
||||
// - If the function fails, the key object will be in an invalid state.
|
||||
//
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmsskeySetValue(
|
||||
_In_reads_bytes_( cbSrc ) PCBYTE pbInput,
|
||||
SIZE_T cbInput,
|
||||
SYMCRYPT_XMSSKEY_TYPE keyType,
|
||||
UINT32 flags,
|
||||
_Inout_ PSYMCRYPT_XMSS_KEY pKey );
|
||||
//
|
||||
// Set an XMSS/XMSS^MT public/private key from key blob
|
||||
//
|
||||
// Key formats:
|
||||
//
|
||||
// PubKey: algId | Root | Seed
|
||||
// PrvKey: algId | Root | Seed | Idx | SK_XMSS | SK_PRF
|
||||
//
|
||||
// algId and Idx are 32-bit and 64-bit integers respectively, stored in big-endian format.
|
||||
// Other values are n-bytes where n is the output size (in bytes) of the hash
|
||||
// algorithm (or the truncated size if the hash output is truncated).
|
||||
//
|
||||
// Public-key format is specified in RFC 8391, whereas private-key format is not.
|
||||
// We define the private-key as an extension of the public-key with the private key
|
||||
// material.
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// (pbInput, cbInput). Input key blob to import the key from
|
||||
//
|
||||
// keyType. Indicates whether (pbInput, cbInput) contains a public or a private key.
|
||||
// Must be one of SYMCRYPT_XMSSKEY_TYPE_PUBLIC, or SYMCRYPT_XMSSKEY_TYPE_PRIVATE.
|
||||
//
|
||||
// flags. See below
|
||||
//
|
||||
// pKey. Pointer to the XMSS key object to be initialized from the key blob
|
||||
//
|
||||
// Allowed flags:
|
||||
//
|
||||
// - SYMCRYPT_FLAG_XMSSKEY_VERIFY_ROOT
|
||||
// Can only be specified when importing a private key. Recomputes the
|
||||
// public root value and compares it to the one that is imported from the
|
||||
// key blob.
|
||||
//
|
||||
// Return values:
|
||||
//
|
||||
// - SYMCRYPT_NO_ERROR
|
||||
// On successfully updating the key object from the provided key blob
|
||||
//
|
||||
// - SYMCRYPT_INVALID_ARGUMENT
|
||||
// If cbInput does not match a public/private key size indicated by keyType parameter
|
||||
// If an invalid flag is specified, or SYMCRYPT_FLAG_XMSSKEY_VERIFY_ROOT is
|
||||
// specified when setting a public key
|
||||
//
|
||||
// - SYMCRYPT_INLVALID_BLOB
|
||||
// If the XMSS algorithm ID in the key blob does not match the algorithm ID
|
||||
// used in creating the key object pointed to by pKey
|
||||
//
|
||||
// - SYMCRYPT_MEMORY_ALLOCATION_FAILURE
|
||||
// If there is not sufficient memory for public root verification (only if
|
||||
// SYMCRYPT_FLAG_XMSSKEY_VERIFY_ROOT is set in flags)
|
||||
//
|
||||
// - SYMCRYPT_HBS_PUBLIC_ROOT_MISMATCH
|
||||
// If public root value in the key blob does not match the recomputed root value
|
||||
// (only if key blob is for a private key and SYMCRYPT_FLAG_XMSSKEY_VERIFY_ROOT is
|
||||
// specified)
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// - The key blob size pbInput must match the size returned by SymCryptXmssSizeofKeyBlobFromParams
|
||||
// for the same keyType and XMSS parameters the key object is created with.
|
||||
// - If the function fails, the key object will be in an invalid state.
|
||||
//
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmsskeyGetValue(
|
||||
_In_ PCSYMCRYPT_XMSS_KEY pKey,
|
||||
SYMCRYPT_XMSSKEY_TYPE keyType,
|
||||
UINT32 flags,
|
||||
_Out_writes_bytes_( cbKey ) PBYTE pbOutput,
|
||||
SIZE_T cbOutput );
|
||||
//
|
||||
// Get public/private key value from an XMSS/XMSS^MT key object
|
||||
//
|
||||
// Key formats:
|
||||
//
|
||||
// PubKey: algId | Root | Seed
|
||||
// PrvKey: algId | Root | Seed | Idx | SK_XMSS | SK_PRF
|
||||
//
|
||||
// algId and Idx are 32-bit and 64-bit integers respectively, stored in big-endian format.
|
||||
// Other values are n-bytes where n is the output size (in bytes) of the hash
|
||||
// algorithm (or the truncated size if the hash output is truncated).
|
||||
//
|
||||
// Public-key format is specified in RFC 8391, whereas private-key format is not.
|
||||
// We define the private-key as an extension of the public-key with the private key
|
||||
// material.
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// pKey. The key object to export the key material from
|
||||
//
|
||||
// keyType. Type of the key (public or private) to get. If the key object
|
||||
// contains a public key, keyType must be SYMCRYPT_XMSSKEY_TYPE_PUBLIC. If
|
||||
// the key object contains a private key, keyType can be one of
|
||||
// SYMCRYPT_XMSSKEY_TYPE_PUBLIC or SYMCRYPT_XMSSKEY_TYPE_PRIVATE
|
||||
//
|
||||
// flags. No flags defined for this function
|
||||
//
|
||||
// (pbOutput, cbOutput). Buffer to store the exported key blob. cbOutput must match
|
||||
// the size of the key to be exported, which can be queried by calling
|
||||
// SymCryptXmssSizeofKeyBlobFromParams.
|
||||
//
|
||||
// Return values:
|
||||
//
|
||||
// - SYMCRYPT_NO_ERROR
|
||||
// On successful exporting of the key
|
||||
//
|
||||
// - SYMCRYPT_INVALID_ARGUMENT
|
||||
// If cbOutput does not match the exact size of the key blob for the specified
|
||||
// keyType
|
||||
// If the key object does not contain private key material when keyType
|
||||
// equals SYMCRYPT_XMSSKEY_TYPE_PRIVATE
|
||||
// If unsupported flags are specified in flags parameter
|
||||
//
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmsskeyFree(
|
||||
_Inout_ PSYMCRYPT_XMSS_KEY pKey);
|
||||
//
|
||||
// Free an allocated XMSS/XMSS^MT key object
|
||||
//
|
||||
|
||||
SIZE_T
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssSizeofSignatureFromParams(
|
||||
_In_ PCSYMCRYPT_XMSS_PARAMS pParams );
|
||||
//
|
||||
// Return the size of the signature for given XMSS parameters
|
||||
//
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssSign(
|
||||
_Inout_ PSYMCRYPT_XMSS_KEY pKey,
|
||||
_In_reads_bytes_( cbMessage ) PCBYTE pbMessage,
|
||||
SIZE_T cbMessage,
|
||||
UINT32 flags,
|
||||
_Out_writes_bytes_( cbSignature ) PBYTE pbSignature,
|
||||
SIZE_T cbSignature );
|
||||
//
|
||||
// Sign a message using XMSS/XMSS^MT
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// pKey. Private XMSS/XMSS^MT key used in signing
|
||||
//
|
||||
// (pbMessage, cbMessage). Message to be signed
|
||||
//
|
||||
// flags. No flags defined for this function
|
||||
//
|
||||
// (pbSignature, cbSignature). Buffer to store the generated signature
|
||||
//
|
||||
// Requirements:
|
||||
//
|
||||
// pKey must contain the private key
|
||||
//
|
||||
// cbSignature must be equal to the generated signature size
|
||||
//
|
||||
// Return values:
|
||||
//
|
||||
// - SYMCRYPT_NO_ERROR on successfull signature generation
|
||||
//
|
||||
// - SYMCRYPT_INVALID_ARGUMENT
|
||||
// If flags parameter is invalid,
|
||||
// or if the key object does not contain private key,
|
||||
// or cbSignature is not of correct size
|
||||
//
|
||||
// - SYMCRYPT_HBS_NO_OTS_KEYS_LEFT
|
||||
// If the key doesn't have any one-time-signatures left for signing
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// The input pbMessage can be of arbitrary length and its randomized hash will be the actual
|
||||
// value that is going to be signed with a WOTSP signature. Applications wanting to pass the hash
|
||||
// value of a message to be signed as opposed to the message itself must make sure to have
|
||||
// domain separation between the space of messages and the hashes of the messages.
|
||||
//
|
||||
// The signature size can be queried with SymCryptSizeofXmssSignatureFromParams function.
|
||||
//
|
||||
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssVerify(
|
||||
_Inout_ PSYMCRYPT_XMSS_KEY pKey,
|
||||
_In_reads_bytes_( cbMessage ) PCBYTE pbMessage,
|
||||
SIZE_T cbMessage,
|
||||
UINT32 flags,
|
||||
_In_reads_bytes_( cbSignature ) PCBYTE pbSignature,
|
||||
SIZE_T cbSignature );
|
||||
//
|
||||
// Verify an XMSS/XMSS^MT signature on a message
|
||||
//
|
||||
// Parameters:
|
||||
//
|
||||
// pKey. XMSS key used to verify the signature
|
||||
//
|
||||
// (pbMessage, cbMessage) Message for which the signature was created
|
||||
//
|
||||
// flags. No flags defined for this function
|
||||
//
|
||||
// (pbSignature, cbSignature) XMSS or XMSS^MT signature
|
||||
//
|
||||
// Return values:
|
||||
//
|
||||
// - SYMCRYPT_NO_ERROR
|
||||
// If signature verification succeeeds
|
||||
//
|
||||
// - SYMCRYPT_INVALID_ARGUMENT
|
||||
// If flags is invalid or cbSignature is of incorrect size
|
||||
//
|
||||
// - SYMCRYPT_SIGNATURE_VERIFICATION_ERROR
|
||||
// If the signature is not valid
|
||||
//
|
||||
// Requirements:
|
||||
//
|
||||
// cbSignature must be equal to the exact signature size associated with
|
||||
// the XMSS parameters.
|
||||
//
|
||||
// Remarks:
|
||||
//
|
||||
// In XMSS, the message can be arbitrarily long and a randomized hash of the message
|
||||
// will be computed first to be signed by the WOTSP internally.
|
||||
//
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssSelftest(void);
|
||||
//
|
||||
// FIPS self-test for signature verification
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// SymCryptFatal
|
||||
//
|
||||
|
|
|
@ -2784,6 +2784,42 @@ SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_802_11_SAE_CUSTOM_STATE {
|
|||
BYTE counter;
|
||||
};
|
||||
|
||||
//
|
||||
// XMSS
|
||||
//
|
||||
|
||||
typedef SYMCRYPT_ALIGN_STRUCT _SYMCRYPT_XMSS_PARAMS
|
||||
{
|
||||
PCSYMCRYPT_HASH hash; // hash function
|
||||
UINT32 id; // algorithm identifier
|
||||
UINT32 cbHashOutput; // hash function output size, must be less than or equal to hash->resultSize
|
||||
UINT32 nWinternitzWidth;// Wintertnitz coefficient, width of digits in bits (chain length = 2^nWinternitzWidth)
|
||||
UINT32 nTotalTreeHeight;// number of layers times the tree height of one layer (each layer has the same height)
|
||||
UINT32 nLayers; // hyper-tree layers, 1 for single tree
|
||||
UINT32 cbPrefix; // length of the domain separator prefix in PRFs
|
||||
|
||||
//
|
||||
// The following are derived from the above
|
||||
//
|
||||
UINT32 len1; // number of w-bit digits in the hash output to be signed ( len1 = ceil(8n / w) )
|
||||
UINT32 len2; // number of w-bit digits in the checksum
|
||||
UINT32 len; // len1 + len2
|
||||
UINT32 nLayerHeight; // tree height of a single layer (h / d)
|
||||
UINT32 cbIdx; // size of leaf counter in bytes (for single trees cbIdx = 4)
|
||||
UINT32 nLeftShift32; // left shift count to align the checksum digits to MSB of a 32-bit word
|
||||
|
||||
BYTE Reserved[16]; // Reserved for future use
|
||||
} SYMCRYPT_XMSS_PARAMS;
|
||||
|
||||
typedef SYMCRYPT_XMSS_PARAMS* PSYMCRYPT_XMSS_PARAMS;
|
||||
typedef const SYMCRYPT_XMSS_PARAMS* PCSYMCRYPT_XMSS_PARAMS;
|
||||
|
||||
struct _SYMCRYPT_XMSS_KEY;
|
||||
typedef struct _SYMCRYPT_XMSS_KEY SYMCRYPT_XMSS_KEY;
|
||||
typedef SYMCRYPT_XMSS_KEY* PSYMCRYPT_XMSS_KEY;
|
||||
typedef const SYMCRYPT_XMSS_KEY* PCSYMCRYPT_XMSS_KEY;
|
||||
|
||||
|
||||
|
||||
#ifndef _PREFAST_
|
||||
#if SYMCRYPT_CPU_X86
|
||||
|
|
|
@ -116,6 +116,7 @@ set(SOURCES_COMMON
|
|||
tlsCbcVerify.c
|
||||
tlsprf_selftest.c
|
||||
tlsprf.c
|
||||
xmss.c
|
||||
xtsaes.c
|
||||
)
|
||||
|
||||
|
|
|
@ -486,6 +486,97 @@ const BYTE rgbSha256Hash[] =
|
|||
};
|
||||
|
||||
|
||||
// XMSS-SHA2_10_192 public-key and signature for message "abc"
|
||||
const BYTE rgbXmssSha2_10_192Pubkey[] =
|
||||
{
|
||||
// Algorithm ID
|
||||
0x00, 0x00, 0x00, 0x0d,
|
||||
|
||||
// Root
|
||||
0x7e, 0x63, 0xd5, 0x1d, 0xdf, 0x92, 0x0f, 0x10,
|
||||
0x63, 0x52, 0x82, 0x38, 0xdf, 0x15, 0x0e, 0x83,
|
||||
0x5c, 0x74, 0x0a, 0x25, 0x10, 0xc8, 0x3b, 0xdc,
|
||||
|
||||
// Seed
|
||||
0x75, 0x78, 0x08, 0x77, 0xb0, 0x90, 0x02, 0x63,
|
||||
0x45, 0x4b, 0xf9, 0xad, 0xee, 0x52, 0x04, 0x75,
|
||||
0x45, 0x13, 0x99, 0xdd, 0x9f, 0xbb, 0xc7, 0x43,
|
||||
};
|
||||
|
||||
const BYTE rgbXmssSha2_10_192Signature[] =
|
||||
{
|
||||
// Idx
|
||||
0x00, 0x00, 0x00, 0x03,
|
||||
|
||||
// Randomness
|
||||
0xf8, 0xbe, 0x24, 0x0e, 0x21, 0x1f, 0x9b, 0x7f, 0x3a, 0x81, 0x82, 0x32, 0x79, 0xe2, 0x2f, 0x42, 0xa5, 0x5a, 0xea, 0x32, 0x75, 0x58, 0x47, 0x8a,
|
||||
|
||||
// WOTSP signature
|
||||
0x2d, 0xaa, 0x55, 0xc6, 0xdb, 0xa4, 0x46, 0x83, 0xda, 0x62, 0xba, 0x67, 0x1a, 0xa2, 0x53, 0x4a, 0xbf, 0xf4, 0x0c, 0x4e, 0x8d, 0xa6, 0x3b, 0xdf,
|
||||
0x92, 0x1c, 0x80, 0xb7, 0xe6, 0x58, 0x66, 0xf3, 0x5d, 0x01, 0xd7, 0x31, 0x70, 0x7e, 0x22, 0x04, 0x73, 0xb0, 0xaa, 0x7a, 0x64, 0xf9, 0xba, 0xf5,
|
||||
0x37, 0x58, 0x98, 0x7e, 0x9c, 0x81, 0xd4, 0xa5, 0xe0, 0x2e, 0xed, 0x6b, 0x61, 0x57, 0xe5, 0x73, 0x80, 0x42, 0x79, 0xe2, 0x30, 0x9d, 0xa8, 0x9c,
|
||||
0x0c, 0x10, 0x1f, 0xb9, 0xf5, 0xa0, 0x17, 0x0e, 0xa0, 0x99, 0xa4, 0xd8, 0x42, 0xea, 0x90, 0xa3, 0xb0, 0x20, 0x89, 0x02, 0x35, 0xfe, 0x86, 0x2e,
|
||||
0x9a, 0x72, 0x41, 0x72, 0x77, 0xb6, 0xbd, 0x30, 0x05, 0xb0, 0xfa, 0xb4, 0x43, 0xc9, 0xfe, 0x54, 0x3f, 0x78, 0x83, 0x87, 0x1a, 0x10, 0xeb, 0x8a,
|
||||
0xf3, 0xbe, 0x59, 0x67, 0x86, 0x26, 0x6e, 0xa2, 0xff, 0xaa, 0xb1, 0xa4, 0xb3, 0xcb, 0xfd, 0xe5, 0x31, 0xb3, 0xd4, 0x2a, 0x02, 0x5e, 0xea, 0xfb,
|
||||
0xea, 0x95, 0x70, 0xa2, 0x56, 0xe9, 0x9e, 0xd1, 0x84, 0x0b, 0xd4, 0xc8, 0xa3, 0xee, 0x46, 0x48, 0x96, 0x1f, 0x30, 0x7d, 0x86, 0x63, 0x47, 0x18,
|
||||
0xb2, 0xe2, 0x3b, 0xe3, 0x89, 0x28, 0x5b, 0x6f, 0x5d, 0x2a, 0xe4, 0xe5, 0x3e, 0xb2, 0x2a, 0x97, 0x00, 0x04, 0xe7, 0xe3, 0x87, 0xa3, 0x6b, 0x73,
|
||||
0xe3, 0xcd, 0x99, 0x5a, 0x8b, 0x93, 0x6a, 0x28, 0x53, 0x66, 0x5b, 0x21, 0x0b, 0x88, 0x2f, 0x01, 0x31, 0x37, 0x03, 0x21, 0xf9, 0xd6, 0x47, 0x99,
|
||||
0x75, 0x81, 0x27, 0x7b, 0x24, 0xa4, 0x23, 0x32, 0x33, 0x6b, 0x3b, 0x8f, 0xe3, 0x5b, 0x38, 0xcc, 0xa5, 0x53, 0xb0, 0x15, 0xd3, 0xc8, 0x42, 0x75,
|
||||
0x2d, 0x73, 0x5a, 0x80, 0x01, 0x10, 0x66, 0x48, 0xf6, 0x3e, 0x36, 0x84, 0xc8, 0xc0, 0x7a, 0xf6, 0xfb, 0xe1, 0xe8, 0x15, 0x3e, 0x9e, 0x0c, 0xd0,
|
||||
0x0c, 0x45, 0x82, 0xa3, 0xfa, 0x8a, 0x0b, 0x6f, 0x84, 0x0b, 0x98, 0xf9, 0x58, 0x88, 0xb8, 0x13, 0xc7, 0xd7, 0x4e, 0x91, 0x89, 0x2f, 0xc0, 0x6f,
|
||||
0x00, 0xf1, 0x6d, 0x67, 0xea, 0xb8, 0xae, 0xbb, 0xa9, 0x12, 0xcb, 0xe6, 0x69, 0xd6, 0x0e, 0xb3, 0xfb, 0xa8, 0xb0, 0x42, 0x06, 0x64, 0x25, 0x07,
|
||||
0xcc, 0xb7, 0xa8, 0x05, 0x51, 0xc2, 0x9f, 0xe9, 0xed, 0x59, 0xb9, 0xb0, 0x9d, 0x4c, 0x56, 0x8e, 0xc2, 0x48, 0xf6, 0x4a, 0x8b, 0x71, 0x90, 0xa1,
|
||||
0x3c, 0xd2, 0xf5, 0xab, 0x74, 0xca, 0xaf, 0x1c, 0x31, 0xa6, 0x45, 0x30, 0x89, 0xb4, 0xe1, 0x4a, 0x82, 0x08, 0x75, 0x46, 0x16, 0xd8, 0x1e, 0x8a,
|
||||
0x42, 0x6c, 0xa0, 0x63, 0x71, 0x41, 0x4f, 0x50, 0xa8, 0xa2, 0x61, 0xcf, 0xb7, 0xd7, 0x4d, 0x91, 0x55, 0xf2, 0xf2, 0xdf, 0xf6, 0xe2, 0xac, 0xb3,
|
||||
0x6f, 0x54, 0x32, 0xb9, 0xf0, 0x3d, 0x8e, 0xf3, 0x04, 0xae, 0xdd, 0x8f, 0x53, 0xb9, 0x8b, 0xe3, 0xcc, 0x3d, 0xbc, 0x54, 0xe4, 0xc4, 0x7c, 0x6d,
|
||||
0x10, 0xfe, 0xd6, 0xeb, 0x12, 0xeb, 0xd1, 0xb1, 0x0a, 0x74, 0x56, 0x81, 0x3a, 0x05, 0x45, 0x65, 0x37, 0x0e, 0x8c, 0x0c, 0x0d, 0xad, 0x3e, 0x91,
|
||||
0xc7, 0x9a, 0x3c, 0xe6, 0xd7, 0x3a, 0xfb, 0x9f, 0x54, 0x66, 0x03, 0x0d, 0x9e, 0x18, 0xe5, 0xa2, 0x19, 0xca, 0x3a, 0xaa, 0x99, 0x6f, 0xe8, 0x15,
|
||||
0xe3, 0x47, 0x4b, 0x90, 0x93, 0x17, 0x89, 0xda, 0x13, 0xff, 0xe5, 0xad, 0x8b, 0xd5, 0xe8, 0xeb, 0x25, 0x3e, 0x10, 0x66, 0x8e, 0x13, 0x01, 0x4d,
|
||||
0xc1, 0xc9, 0x17, 0x56, 0x4e, 0x23, 0xef, 0x34, 0x22, 0xed, 0x8d, 0x84, 0x7c, 0xd8, 0x42, 0x7b, 0x72, 0x3d, 0x45, 0x1f, 0x23, 0x60, 0x46, 0x1d,
|
||||
0x60, 0xb4, 0xaf, 0x6d, 0xb9, 0xc3, 0xe3, 0xd4, 0x05, 0xee, 0x24, 0xb7, 0x1e, 0xbe, 0x37, 0x3d, 0x62, 0xc5, 0xe1, 0x6c, 0xd7, 0xc3, 0x43, 0xf4,
|
||||
0x1c, 0x8b, 0x95, 0xb8, 0x31, 0x0d, 0x6f, 0x51, 0x0b, 0xb8, 0xf0, 0x87, 0xf2, 0x94, 0x5c, 0x25, 0x2d, 0x84, 0x9a, 0x3b, 0x6b, 0x13, 0x61, 0xd6,
|
||||
0x94, 0xa9, 0x53, 0x30, 0xd1, 0x00, 0x82, 0xb1, 0x04, 0x29, 0x78, 0x43, 0x60, 0x92, 0x39, 0xf0, 0x9a, 0xfe, 0xfb, 0x5c, 0x7c, 0x5e, 0x5e, 0x54,
|
||||
0xcc, 0x9e, 0xf7, 0x67, 0x1c, 0x15, 0x6b, 0xa4, 0x5d, 0x90, 0xdd, 0x5c, 0x82, 0xef, 0x12, 0xca, 0x0f, 0x42, 0xc7, 0x54, 0x0b, 0xfb, 0x8a, 0xc5,
|
||||
0xfe, 0x6f, 0xdc, 0x95, 0x09, 0xd9, 0x7c, 0x19, 0xc6, 0x66, 0x8a, 0xff, 0x45, 0x2d, 0x59, 0xd1, 0x82, 0xdd, 0x56, 0xaa, 0x65, 0xf7, 0x37, 0x76,
|
||||
0x66, 0xc4, 0x4d, 0x70, 0x4b, 0xc8, 0x3f, 0x47, 0xc2, 0xe8, 0xd3, 0xb6, 0xe4, 0x4e, 0xa7, 0xc3, 0x0a, 0x29, 0x69, 0x57, 0xba, 0x64, 0x23, 0xd4,
|
||||
0x75, 0x74, 0x12, 0x85, 0xf8, 0x42, 0x1d, 0xc9, 0xd0, 0x65, 0x5a, 0x8f, 0xed, 0x49, 0xbb, 0x3d, 0x2e, 0xe5, 0xee, 0x14, 0x95, 0xc1, 0x92, 0xf6,
|
||||
0xf7, 0xac, 0xe1, 0x07, 0x00, 0x6c, 0x9b, 0xd9, 0xa8, 0x41, 0x96, 0xdc, 0x8b, 0x07, 0x05, 0xb8, 0x16, 0x54, 0x34, 0x29, 0xf9, 0x3e, 0x5a, 0x86,
|
||||
0x82, 0x93, 0xa2, 0x5f, 0xf8, 0x4b, 0x3c, 0x52, 0xf8, 0x5a, 0x62, 0x0e, 0x01, 0xe0, 0x26, 0xcd, 0x3b, 0x04, 0xa8, 0xe1, 0x00, 0xc9, 0x06, 0x16,
|
||||
0x51, 0x79, 0xaa, 0xb4, 0x56, 0x44, 0x08, 0x20, 0x17, 0xc1, 0x2f, 0x17, 0xc5, 0x8c, 0xbb, 0xad, 0x8c, 0x28, 0x53, 0x29, 0x1c, 0xde, 0xf1, 0xa3,
|
||||
0xa1, 0x04, 0x1d, 0x01, 0x7f, 0xe5, 0xa8, 0xb2, 0xea, 0xb6, 0x4b, 0x7b, 0x3e, 0x3b, 0x50, 0x6b, 0x2a, 0x72, 0x5a, 0x5e, 0xd7, 0x9b, 0xf4, 0x16,
|
||||
0x1f, 0xec, 0x18, 0x2f, 0xc7, 0xa0, 0xb2, 0xb5, 0x25, 0xd0, 0x34, 0x64, 0x89, 0x00, 0x00, 0x85, 0xab, 0x6e, 0x90, 0x31, 0x3f, 0x91, 0x59, 0x35,
|
||||
0x5c, 0x88, 0x25, 0xe6, 0xc3, 0x79, 0xde, 0x27, 0x8a, 0xab, 0x40, 0x4f, 0x17, 0xba, 0x04, 0xc7, 0x1a, 0xd9, 0x36, 0x92, 0x9c, 0x6a, 0x3c, 0xc8,
|
||||
0x28, 0x6b, 0x2d, 0x15, 0x86, 0x6c, 0xe4, 0x4d, 0x48, 0x70, 0xbb, 0x09, 0xeb, 0xa9, 0x69, 0xef, 0xff, 0xee, 0xed, 0xbf, 0x82, 0x61, 0xb3, 0x3d,
|
||||
0x63, 0x70, 0xfb, 0x4c, 0x8c, 0x1d, 0xca, 0xf4, 0x6f, 0x10, 0x36, 0x3b, 0x00, 0x65, 0x0c, 0x40, 0x47, 0x4c, 0xbb, 0x9f, 0x7a, 0x53, 0x72, 0x91,
|
||||
0x6d, 0x4a, 0xe0, 0xf4, 0x89, 0xeb, 0x53, 0x99, 0x1a, 0x1a, 0xf3, 0xee, 0xc3, 0x93, 0xc7, 0x30, 0x3f, 0x61, 0xb6, 0xab, 0x6f, 0x0a, 0xab, 0xa8,
|
||||
0xbf, 0x33, 0x69, 0x82, 0xda, 0x12, 0xc8, 0xab, 0x8f, 0x01, 0x84, 0x30, 0x51, 0xf3, 0x12, 0xc5, 0xe2, 0x1c, 0xb7, 0x63, 0xb8, 0x14, 0x33, 0x5f,
|
||||
0x7b, 0x9a, 0x68, 0x4f, 0x27, 0xf9, 0x40, 0xa0, 0xad, 0x23, 0xf5, 0xf2, 0xf4, 0x78, 0xc4, 0x93, 0x2d, 0xfc, 0xe8, 0xea, 0x5c, 0x00, 0x2a, 0x13,
|
||||
0x4f, 0x2b, 0x5b, 0x26, 0x39, 0x50, 0xaf, 0x52, 0x33, 0xdd, 0xcd, 0xf3, 0x86, 0x53, 0x8f, 0xc6, 0xfe, 0x87, 0x2e, 0x73, 0xab, 0x34, 0xcb, 0xd4,
|
||||
0xc8, 0x76, 0x9d, 0x00, 0xd7, 0x98, 0x5b, 0x85, 0x95, 0x75, 0xcd, 0xb0, 0x07, 0xa6, 0xaf, 0xa8, 0xf5, 0x58, 0x2e, 0xc8, 0xd0, 0x50, 0x7c, 0xc2,
|
||||
0x1e, 0x71, 0x86, 0x86, 0xdb, 0x72, 0xcc, 0x68, 0x78, 0x51, 0x6d, 0xe1, 0x13, 0xdc, 0x6c, 0x89, 0xa6, 0x4a, 0xf5, 0x43, 0xf3, 0x29, 0x31, 0xbe,
|
||||
0x16, 0xab, 0x8b, 0xdf, 0x52, 0x0a, 0xc1, 0x7d, 0x04, 0x57, 0x39, 0xbb, 0x9a, 0x8d, 0x64, 0x7f, 0xf1, 0x64, 0x9e, 0xfc, 0x12, 0x8b, 0x84, 0x85,
|
||||
0x5e, 0x93, 0x35, 0xa6, 0x18, 0xcb, 0xbb, 0x1f, 0x37, 0xda, 0xc2, 0x19, 0xa3, 0x6e, 0x31, 0x8a, 0xa5, 0x50, 0xea, 0x70, 0xe1, 0x72, 0x20, 0x35,
|
||||
0x09, 0x47, 0xa3, 0xc8, 0xbc, 0x23, 0xdf, 0x9c, 0x26, 0x36, 0x1b, 0x5a, 0x1f, 0x5f, 0x33, 0x81, 0xd6, 0xbd, 0x94, 0x84, 0x06, 0x81, 0x80, 0x1a,
|
||||
0xbd, 0x01, 0x9f, 0x4c, 0x66, 0x79, 0xc1, 0x2f, 0x84, 0x3a, 0xbb, 0x30, 0x68, 0xce, 0xd3, 0x94, 0xec, 0x92, 0xee, 0xd2, 0xe5, 0x28, 0x3f, 0xdd,
|
||||
0x3f, 0xf1, 0x8d, 0x71, 0x5a, 0x56, 0xe3, 0x88, 0x2c, 0x6e, 0x6f, 0xd7, 0x41, 0x41, 0xa4, 0xa6, 0xcb, 0x38, 0xfd, 0x8e, 0x18, 0xde, 0x7c, 0xd2,
|
||||
0x9d, 0xec, 0xae, 0xac, 0xce, 0x5b, 0x20, 0x6f, 0x43, 0x06, 0x70, 0x1b, 0x1a, 0x10, 0xfd, 0x1c, 0x24, 0x8a, 0x99, 0xa2, 0x6e, 0xde, 0x2c, 0xfe,
|
||||
0xd2, 0x49, 0xe7, 0xa3, 0x4b, 0x76, 0x1a, 0xf1, 0xee, 0xee, 0xd3, 0xb5, 0x1c, 0xb1, 0xdc, 0x20, 0xe5, 0x5c, 0x8d, 0x83, 0xa6, 0xf8, 0x12, 0x2e,
|
||||
0x6c, 0x6a, 0x2e, 0x16, 0x23, 0xed, 0x3c, 0x96, 0x52, 0x9c, 0x51, 0x0f, 0x2d, 0xbe, 0x1b, 0x3d, 0x6a, 0xd2, 0xf5, 0x43, 0xde, 0x7a, 0x5c, 0x07,
|
||||
0x85, 0x42, 0x89, 0x49, 0xa6, 0x08, 0x82, 0x13, 0xcd, 0xa1, 0xd5, 0x7d, 0x86, 0x51, 0x9b, 0x20, 0x44, 0x59, 0x71, 0x24, 0x72, 0xcc, 0xf0, 0x69,
|
||||
|
||||
// Authentication nodes
|
||||
0x51, 0x4f, 0x87, 0x42, 0xee, 0x41, 0x95, 0x4d, 0x7c, 0x77, 0x36, 0x33, 0x58, 0x8c, 0xaa, 0x8e, 0x24, 0x53, 0xaf, 0x69, 0xdc, 0x0a, 0xd9, 0x62,
|
||||
0x5b, 0x42, 0xf1, 0x46, 0xcd, 0x85, 0x59, 0x18, 0x85, 0x48, 0xd3, 0x4c, 0xbe, 0xd6, 0xb3, 0x36, 0x3f, 0x1f, 0x2b, 0x30, 0x13, 0x87, 0x2b, 0xd5,
|
||||
0xcd, 0xb7, 0x6b, 0x19, 0x68, 0x16, 0x91, 0x25, 0xc2, 0x0e, 0xbe, 0xb6, 0xbb, 0x6d, 0xe1, 0x37, 0x4d, 0x4c, 0x0a, 0x80, 0x02, 0x01, 0xdd, 0xfb,
|
||||
0x0e, 0xb3, 0xaa, 0xf9, 0x83, 0x0d, 0x44, 0x72, 0x64, 0x5b, 0xec, 0xbf, 0xe0, 0x98, 0xd7, 0x4f, 0x09, 0x85, 0xf9, 0x99, 0x88, 0x78, 0xa7, 0xad,
|
||||
0x6b, 0xce, 0xa3, 0xa0, 0x74, 0x72, 0xe1, 0x3a, 0x39, 0x29, 0x3f, 0x1b, 0xcd, 0xfe, 0x60, 0x54, 0xf5, 0xdb, 0xa3, 0xd6, 0x21, 0xde, 0x8c, 0x6f,
|
||||
0x33, 0x52, 0x0c, 0xfb, 0x61, 0x60, 0x88, 0xb3, 0x17, 0x8a, 0xe5, 0x4a, 0xaa, 0x5b, 0x64, 0x01, 0x33, 0x57, 0x46, 0x91, 0x61, 0x95, 0x93, 0x08,
|
||||
0xe8, 0x0d, 0xba, 0xda, 0x0c, 0xeb, 0x96, 0x7b, 0x73, 0xa5, 0x79, 0xe4, 0x0b, 0x93, 0x51, 0x28, 0xa3, 0x44, 0x76, 0x62, 0xe6, 0xbe, 0xca, 0x0e,
|
||||
0x37, 0x7b, 0xf6, 0xfb, 0xbd, 0x6c, 0xd7, 0x8f, 0xba, 0x75, 0xd5, 0x6b, 0xc1, 0xc2, 0x04, 0xfa, 0xf8, 0xe3, 0x07, 0x10, 0x6f, 0xb4, 0x97, 0xf1,
|
||||
0xd7, 0xa8, 0x83, 0xa9, 0x9f, 0x20, 0x9c, 0xfc, 0xa7, 0x45, 0x71, 0x36, 0xeb, 0x26, 0xc7, 0x1d, 0x8a, 0x3c, 0x66, 0x78, 0x02, 0xc5, 0x76, 0xa1,
|
||||
0xd5, 0xc2, 0x15, 0x86, 0x2e, 0x8a, 0x46, 0xde, 0x45, 0xcf, 0xaf, 0xdd, 0xe3, 0xbe, 0xb6, 0x5e, 0x88, 0x1f, 0x9e, 0x63, 0xa6, 0xca, 0x89, 0x8b,
|
||||
};
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptDhSecretAgreementSelftest(void)
|
||||
|
@ -847,4 +938,58 @@ SymCryptRsaSelftest(void)
|
|||
SymCryptRsaSignVerifyTest( pkRsakey );
|
||||
|
||||
SymCryptRsakeyFree( pkRsakey );
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssVerifySelftest(void)
|
||||
{
|
||||
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
|
||||
PSYMCRYPT_XMSS_KEY pKey = NULL;
|
||||
SYMCRYPT_XMSS_PARAMS params;
|
||||
PBYTE pbSignature;
|
||||
SIZE_T cbSignature = sizeof(rgbXmssSha2_10_192Signature);
|
||||
|
||||
scError = SymCryptXmssParamsFromAlgId(SYMCRYPT_XMSS_SHA2_10_192, ¶ms);
|
||||
SYMCRYPT_FIPS_ASSERT(scError == SYMCRYPT_NO_ERROR);
|
||||
|
||||
pKey = SymCryptXmsskeyAllocate(¶ms, 0);
|
||||
SYMCRYPT_FIPS_ASSERT(pKey != NULL);
|
||||
|
||||
scError = SymCryptXmsskeySetValue(
|
||||
rgbXmssSha2_10_192Pubkey,
|
||||
sizeof(rgbXmssSha2_10_192Pubkey),
|
||||
SYMCRYPT_XMSSKEY_TYPE_PUBLIC,
|
||||
0,
|
||||
pKey);
|
||||
|
||||
// Make a copy of the signature so that we can inject errors in it
|
||||
pbSignature = SymCryptCallbackAlloc(cbSignature);
|
||||
SYMCRYPT_FIPS_ASSERT(pbSignature != NULL);
|
||||
memcpy(pbSignature, rgbXmssSha2_10_192Signature, cbSignature);
|
||||
|
||||
SymCryptInjectError(pbSignature, cbSignature);
|
||||
|
||||
scError = SymCryptXmssVerify(
|
||||
pKey,
|
||||
SymCryptTestMsg3,
|
||||
sizeof(SymCryptTestMsg3),
|
||||
0,
|
||||
pbSignature,
|
||||
cbSignature);
|
||||
SYMCRYPT_FIPS_ASSERT(scError == SYMCRYPT_NO_ERROR);
|
||||
|
||||
SymCryptWipe(pbSignature, cbSignature);
|
||||
SymCryptCallbackFree(pbSignature);
|
||||
|
||||
SymCryptXmsskeyFree(pKey);
|
||||
}
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssSelftest(void)
|
||||
{
|
||||
// Perform only signature verification self-test
|
||||
SymCryptXmssVerifySelftest();
|
||||
}
|
||||
|
||||
|
|
241
lib/sc_lib.h
241
lib/sc_lib.h
|
@ -1877,6 +1877,7 @@ SymCryptCShakeEncodeInputStrings(
|
|||
// Appends byte_pad( encode_string( pbFunctionNameString ) || encode_string( pbCustomizationString ), pState->inputBlockSize )
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptFatalIntercept( UINT32 fatalCode );
|
||||
|
@ -4285,6 +4286,217 @@ SymCryptPositiveWidthNafRecoding(
|
|||
PUINT32 absofKIs,
|
||||
UINT32 nRecodedDigits );
|
||||
|
||||
|
||||
|
||||
//
|
||||
// XMSS
|
||||
//
|
||||
|
||||
//
|
||||
// ADRS structure definitions as specified in RFC 8391
|
||||
//
|
||||
typedef enum _XMSS_ADRS_TYPE
|
||||
{
|
||||
XMSS_ADRS_TYPE_OTS = 0,
|
||||
XMSS_ADRS_TYPE_LTREE = 1,
|
||||
XMSS_ADRS_TYPE_HASH_TREE = 2,
|
||||
} XMSS_ADRS_TYPE;
|
||||
|
||||
typedef struct _XMSS_OTS_ADDRESS
|
||||
{
|
||||
BYTE en32Leaf[4];
|
||||
BYTE en32Chain[4];
|
||||
BYTE en32Hash[4];
|
||||
} XMSS_OTS_ADDRESS, *PXMSS_OTS_ADDRESS;
|
||||
|
||||
typedef struct _XMSS_LTREE_ADDRESS
|
||||
{
|
||||
BYTE en32Leaf[4];
|
||||
BYTE en32Height[4];
|
||||
BYTE en32Index[4];
|
||||
} XMSS_LTREE_ADDRESS, * PXMSS_LTREE_ADDRESS;
|
||||
|
||||
typedef struct _XMSS_HASHTREE_ADDRESS
|
||||
{
|
||||
BYTE padding[4];
|
||||
BYTE en32Height[4];
|
||||
BYTE en32Index[4];
|
||||
} XMSS_HASHTREE_ADDRESS, * PXMSS_HASHTREE_ADDRESS;
|
||||
|
||||
typedef struct _XMSS_ADRS
|
||||
{
|
||||
BYTE en32Layer[4];
|
||||
BYTE en64Tree[8];
|
||||
BYTE en32Type[4];
|
||||
|
||||
union {
|
||||
XMSS_OTS_ADDRESS ots;
|
||||
XMSS_LTREE_ADDRESS ltree;
|
||||
XMSS_HASHTREE_ADDRESS hashtree;
|
||||
} u;
|
||||
|
||||
BYTE en32KeyAndMask[4];
|
||||
|
||||
} XMSS_ADRS, *PXMSS_ADRS;
|
||||
|
||||
|
||||
typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_XMSS_KEY
|
||||
{
|
||||
UINT32 version;
|
||||
|
||||
SYMCRYPT_XMSS_PARAMS params;
|
||||
|
||||
SYMCRYPT_XMSSKEY_TYPE keyType;
|
||||
|
||||
// Public key
|
||||
BYTE Root[SYMCRYPT_HASH_MAX_RESULT_SIZE];
|
||||
BYTE Seed[SYMCRYPT_HASH_MAX_RESULT_SIZE];
|
||||
|
||||
SYMCRYPT_MAGIC_FIELD
|
||||
|
||||
// Private key
|
||||
SYMCRYPT_ALIGN_AT(16) UINT64 Idx; // Aligning on 16-bytes to supress clang warning
|
||||
// when atomic increment is performed on it.
|
||||
BYTE SkXmss[SYMCRYPT_HASH_MAX_RESULT_SIZE];
|
||||
BYTE SkPrf[SYMCRYPT_HASH_MAX_RESULT_SIZE];
|
||||
|
||||
} SYMCRYPT_XMSS_KEY;
|
||||
|
||||
typedef SYMCRYPT_XMSS_KEY* PSYMCRYPT_XMSS_KEY;
|
||||
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmssComputePublicRoot(
|
||||
_In_ PCSYMCRYPT_XMSS_PARAMS pParams,
|
||||
_In_reads_bytes_( cbSeed ) PCBYTE pbSeed,
|
||||
SIZE_T cbSeed,
|
||||
_In_reads_bytes_( cbSkXmss ) PCBYTE pbSkXmss,
|
||||
SIZE_T cbSkXmss,
|
||||
_Out_writes_bytes_( cbRoot ) PBYTE pbRoot,
|
||||
SIZE_T cbRoot );
|
||||
//
|
||||
// Compute public root value from SEED and SK_XMSS
|
||||
//
|
||||
|
||||
SYMCRYPT_ERROR
|
||||
SYMCRYPT_CALL
|
||||
SymCryptXmsskeyVerifyRoot(
|
||||
_In_ PCSYMCRYPT_XMSS_KEY pKey );
|
||||
//
|
||||
// Verifies that the public root matches the private key by recomputing it
|
||||
//
|
||||
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsGetWinternitzLengths(
|
||||
UINT32 n, // data size in bytes
|
||||
UINT32 w, // digit length in bits (Winternitz coefficient)
|
||||
_Out_ PUINT32 puLen1, // number of w-bit digits in n
|
||||
_Out_ PUINT32 puLen2 // number of w-bit digits to store the checksum len1 * (2^w - 1)
|
||||
);
|
||||
|
||||
typedef struct _SYMCRYPT_TREEHASH_NODE
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 height;
|
||||
BYTE value[SYMCRYPT_ANYSIZE_ARRAY];
|
||||
} SYMCRYPT_TREEHASH_NODE, * PSYMCRYPT_TREEHASH_NODE;
|
||||
|
||||
#define SYMCRYPT_SIZEOF_TREEHASH_NODE(cbValue) (sizeof(SYMCRYPT_TREEHASH_NODE) - 1 + (cbValue))
|
||||
|
||||
#define SYMCRYPT_TREEHASH_NODE_GET(aNodes, cbValue, i) ((PSYMCRYPT_TREEHASH_NODE)((PBYTE)(aNodes) + (i) * SYMCRYPT_SIZEOF_TREEHASH_NODE(cbValue)))
|
||||
|
||||
|
||||
typedef struct _SYMCRYPT_XMSS_INCREMENTAL_TREEHASH_CONTEXT
|
||||
{
|
||||
PCSYMCRYPT_XMSS_PARAMS pParams;
|
||||
PCBYTE pbSeed;
|
||||
XMSS_ADRS adrs;
|
||||
|
||||
} SYMCRYPT_XMSS_INCREMENTAL_TREEHASH_CONTEXT, * PSYMCRYPT_XMSS_INCREMENTAL_TREEHASH_CONTEXT;
|
||||
|
||||
|
||||
typedef
|
||||
VOID
|
||||
(SYMCRYPT_CALL *PSYMCRYPT_INCREMENTAL_TREEHASH_FUNC)(
|
||||
_In_ PSYMCRYPT_TREEHASH_NODE pNodeLeft,
|
||||
_In_ PSYMCRYPT_TREEHASH_NODE pNodeRight,
|
||||
_Out_ PSYMCRYPT_TREEHASH_NODE pNodeOut,
|
||||
_Inout_ PSYMCRYPT_XMSS_INCREMENTAL_TREEHASH_CONTEXT pContext );
|
||||
|
||||
|
||||
typedef struct _SYMCRYPT_INCREMENTAL_TREEHASH
|
||||
{
|
||||
UINT32 cbNode; // node size; height + hash result
|
||||
UINT32 nSize; // current size of the stack
|
||||
UINT32 nCapacity; // maximum items
|
||||
UINT32 nLastLeafIndex;
|
||||
PSYMCRYPT_INCREMENTAL_TREEHASH_FUNC funcCompressNodes;
|
||||
PSYMCRYPT_XMSS_INCREMENTAL_TREEHASH_CONTEXT pContext;
|
||||
|
||||
SYMCRYPT_TREEHASH_NODE arrNodes[SYMCRYPT_ANYSIZE_ARRAY];
|
||||
|
||||
} SYMCRYPT_INCREMENTAL_TREEHASH, *PSYMCRYPT_INCREMENTAL_TREEHASH;
|
||||
|
||||
|
||||
PSYMCRYPT_INCREMENTAL_TREEHASH
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsIncrementalTreehashInit(
|
||||
UINT32 nLeaves,
|
||||
PBYTE pbBuffer,
|
||||
SIZE_T cbBuffer,
|
||||
UINT32 cbHashResult,
|
||||
PSYMCRYPT_INCREMENTAL_TREEHASH_FUNC funcCompressNodes,
|
||||
PSYMCRYPT_XMSS_INCREMENTAL_TREEHASH_CONTEXT pContext);
|
||||
|
||||
PSYMCRYPT_TREEHASH_NODE
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsIncrementalTreehashGetNode(
|
||||
_In_ PSYMCRYPT_INCREMENTAL_TREEHASH pIncHash,
|
||||
SIZE_T index );
|
||||
|
||||
PSYMCRYPT_TREEHASH_NODE
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsIncrementalTreehashAllocNode(
|
||||
_Inout_ PSYMCRYPT_INCREMENTAL_TREEHASH pIncHash,
|
||||
UINT32 nLeafIndex );
|
||||
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsIncrementalTreehashGetTopNodes(
|
||||
_Inout_ PSYMCRYPT_INCREMENTAL_TREEHASH pIncHash,
|
||||
_Out_ PSYMCRYPT_TREEHASH_NODE *ppNodeLeft,
|
||||
_Out_ PSYMCRYPT_TREEHASH_NODE *ppNodeRight );
|
||||
|
||||
PSYMCRYPT_TREEHASH_NODE
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsIncrementalTreehashProcessCommon(
|
||||
_Inout_ PSYMCRYPT_INCREMENTAL_TREEHASH pIncHash,
|
||||
BOOLEAN fFinal );
|
||||
|
||||
PSYMCRYPT_TREEHASH_NODE
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsIncrementalTreehashProcess(
|
||||
_Inout_ PSYMCRYPT_INCREMENTAL_TREEHASH pIncHash);
|
||||
|
||||
PSYMCRYPT_TREEHASH_NODE
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsIncrementalTreehashFinalize(
|
||||
_Inout_ PSYMCRYPT_INCREMENTAL_TREEHASH pIncHash);
|
||||
|
||||
UINT32
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsIncrementalTreehashStackDepth(
|
||||
UINT32 nLeaves);
|
||||
|
||||
SIZE_T
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsSizeofScratchBytesForIncrementalTreehash(
|
||||
UINT32 cbNode,
|
||||
UINT32 nLeaves);
|
||||
|
||||
// Atomics.
|
||||
//
|
||||
// We define all our SymCrypt atomics below. Different compilers/environments have different
|
||||
|
@ -4499,4 +4711,31 @@ SymCryptCountTrailingZeros32( UINT32 value )
|
|||
#endif
|
||||
|
||||
return (UINT32) index;
|
||||
}
|
||||
}
|
||||
|
||||
FORCEINLINE
|
||||
UINT32
|
||||
SymCryptCountLeadingZeros32( UINT32 value )
|
||||
{
|
||||
ULONG zeros = 0;
|
||||
|
||||
if(value == 0)
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
|
||||
#if SYMCRYPT_MS_VC && (SYMCRYPT_CPU_AMD64 | SYMCRYPT_CPU_ARM64 | SYMCRYPT_CPU_X86 | SYMCRYPT_CPU_ARM)
|
||||
_BitScanReverse(&zeros, value);
|
||||
zeros = 31 - zeros;
|
||||
#elif SYMCRYPT_GNUC
|
||||
zeros = __builtin_clz(value);
|
||||
#else
|
||||
while( (value & 0x80000000) == 0 )
|
||||
{
|
||||
zeros++;
|
||||
value <<= 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (UINT32)zeros;
|
||||
}
|
||||
|
|
|
@ -146,6 +146,7 @@
|
|||
<ClCompile Include="tlsCbcVerify.c" />
|
||||
<ClCompile Include="tlsprf.c" />
|
||||
<ClCompile Include="tlsprf_selftest.c" />
|
||||
<ClCompile Include="xmss.c" />
|
||||
<ClCompile Include="xtsaes.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Platform)'=='x64'">
|
||||
|
@ -180,7 +181,6 @@
|
|||
<Message Importance="high" Text="Generating build info header" />
|
||||
<Exec Command="python ..\scripts\version.py --build-info" />
|
||||
</Target>
|
||||
|
||||
<Target Name="GetDriverProjectAttributes" Returns="@(DriverProjectAttributes)" />
|
||||
<Target Name="GetPackageFiles" Returns="@(FullyQualifiedFilesToPackage)" />
|
||||
</Project>
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -559,4 +559,17 @@ VERSION_103.4
|
|||
SymCryptSskdfMac;
|
||||
SymCryptSskdfHash;
|
||||
SymCryptSskdfSelfTest;
|
||||
SymCryptXmsskeyAllocate;
|
||||
SymCryptXmsskeyFree;
|
||||
SymCryptXmsskeyGenerate;
|
||||
SymCryptXmsskeyGetValue;
|
||||
SymCryptXmsskeySetValue;
|
||||
SymCryptXmssSizeofKeyBlobFromParams;
|
||||
SymCryptXmssMtParamsFromAlgId;
|
||||
SymCryptXmssParamsFromAlgId;
|
||||
SymCryptXmssSetParams;
|
||||
SymCryptXmssSign;
|
||||
SymCryptXmssSizeofSignatureFromParams;
|
||||
SymCryptXmssVerify;
|
||||
SymCryptXmssSelftest;
|
||||
} VERSION_103.2;
|
|
@ -524,6 +524,19 @@ EXPORTS
|
|||
; SymCryptXtsAesExpandKeyEx
|
||||
; SymCryptXtsAesKeyCopy
|
||||
; SymCryptXtsAesSelftest
|
||||
; SymCryptXmsskeyAllocate
|
||||
; SymCryptXmsskeyFree
|
||||
; SymCryptXmsskeyGenerate
|
||||
; SymCryptXmsskeyGetValue
|
||||
; SymCryptXmsskeySetValue
|
||||
; SymCryptXmssSizeofKeyBlobFromParams
|
||||
; SymCryptXmssMtParamsFromAlgId
|
||||
; SymCryptXmssParamsFromAlgId
|
||||
; SymCryptXmssSetParams
|
||||
; SymCryptXmssSign
|
||||
; SymCryptXmssSizeofSignatureFromParams
|
||||
; SymCryptXmssVerify
|
||||
; SymCryptXmssSelftest
|
||||
|
||||
SymCryptDeprecatedStatusIndicator
|
||||
SymCryptEntropyAccumulatorInit0
|
||||
|
|
|
@ -527,3 +527,17 @@ EXPORTS
|
|||
SymCryptXtsAesExpandKeyEx
|
||||
SymCryptXtsAesKeyCopy
|
||||
SymCryptXtsAesSelftest
|
||||
SymCryptXmsskeyAllocate
|
||||
SymCryptXmsskeyFree
|
||||
SymCryptXmsskeyGenerate
|
||||
SymCryptXmsskeyGetValue
|
||||
SymCryptXmsskeySetValue
|
||||
SymCryptXmssSizeofKeyBlobFromParams
|
||||
SymCryptXmssMtParamsFromAlgId
|
||||
SymCryptXmssParamsFromAlgId
|
||||
SymCryptXmssSetParams
|
||||
SymCryptXmssSign
|
||||
SymCryptXmssSizeofSignatureFromParams
|
||||
SymCryptXmssVerify
|
||||
SymCryptXmssSelftest
|
||||
|
|
@ -520,3 +520,16 @@ FUNCTION(SymCryptPaddingPkcs7Add)
|
|||
FUNCTION(SymCryptPaddingPkcs7Remove)
|
||||
FUNCTION(SymCryptFipsGetSelftestsPerformed)
|
||||
FUNCTION(SymCryptDeprecatedStatusIndicator)
|
||||
FUNCTION(SymCryptXmsskeyAllocate)
|
||||
FUNCTION(SymCryptXmsskeyFree)
|
||||
FUNCTION(SymCryptXmsskeyGenerate)
|
||||
FUNCTION(SymCryptXmsskeyGetValue)
|
||||
FUNCTION(SymCryptXmsskeySetValue)
|
||||
FUNCTION(SymCryptXmssSizeofKeyBlobFromParams)
|
||||
FUNCTION(SymCryptXmssMtParamsFromAlgId)
|
||||
FUNCTION(SymCryptXmssParamsFromAlgId)
|
||||
FUNCTION(SymCryptXmssSetParams)
|
||||
FUNCTION(SymCryptXmssSign)
|
||||
FUNCTION(SymCryptXmssSizeofSignatureFromParams)
|
||||
FUNCTION(SymCryptXmssVerify)
|
||||
FUNCTION(SymCryptXmssSelftest)
|
||||
|
|
|
@ -1681,6 +1681,98 @@ public:
|
|||
};
|
||||
|
||||
|
||||
// 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
|
||||
|
@ -1855,6 +1947,15 @@ 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 declaration for performance functions (for those implementations that wish to use them)
|
||||
//
|
||||
|
|
|
@ -571,6 +571,19 @@
|
|||
|
||||
#define ScDispatchSymCryptDeprecatedStatusIndicator(...) SCTEST_CALL_DISPATCHFN(SymCryptDeprecatedStatusIndicator, __VA_ARGS__)
|
||||
|
||||
#define ScDispatchSymCryptXmsskeyAllocate(...) SCTEST_CALL_DISPATCHFN(SymCryptXmsskeyAllocate, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmsskeyFree(...) SCTEST_CALL_DISPATCHFN(SymCryptXmsskeyFree, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmsskeyGenerate(...) SCTEST_CALL_DISPATCHFN(SymCryptXmsskeyGenerate, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmsskeyGetValue(...) SCTEST_CALL_DISPATCHFN(SymCryptXmsskeyGetValue, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmsskeySetValue(...) SCTEST_CALL_DISPATCHFN(SymCryptXmsskeySetValue, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmssSizeofKeyBlobFromParams(...) SCTEST_CALL_DISPATCHFN(SymCryptXmssSizeofKeyBlobFromParams, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmssMtParamsFromAlgId(...) SCTEST_CALL_DISPATCHFN(SymCryptXmssMtParamsFromAlgId, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmssParamsFromAlgId(...) SCTEST_CALL_DISPATCHFN(SymCryptXmssParamsFromAlgId, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmssSetParams(...) SCTEST_CALL_DISPATCHFN(SymCryptXmssSetParams, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmssSign(...) SCTEST_CALL_DISPATCHFN(SymCryptXmssSign, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmssSizeofSignatureFromParams(...) SCTEST_CALL_DISPATCHFN(SymCryptXmssSizeofSignatureFromParams, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmssVerify(...) SCTEST_CALL_DISPATCHFN(SymCryptXmssVerify, __VA_ARGS__)
|
||||
#define ScDispatchSymCryptXmssSelftest(...) SCTEST_CALL_DISPATCHFN(SymCryptXmssSelftest, __VA_ARGS__)
|
||||
|
||||
#define ScDispatchSymCryptMarvin32DefaultSeed SCTEST_GET_DISPATCHSYM(SymCryptMarvin32DefaultSeed)
|
||||
#define ScDispatchSymCryptMd2Algorithm SCTEST_GET_DISPATCHSYM(SymCryptMd2Algorithm)
|
||||
|
|
|
@ -558,6 +558,19 @@
|
|||
|
||||
#define ScShimSymCryptDeprecatedStatusIndicator(...) SCTEST_CALL_SCIMPFN(SymCryptDeprecatedStatusIndicator, __VA_ARGS__)
|
||||
|
||||
#define ScShimSymCryptXmsskeyAllocate(...) SCTEST_CALL_SCIMPFN(SymCryptXmsskeyAllocate, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmsskeyFree(...) SCTEST_CALL_SCIMPFN(SymCryptXmsskeyFree, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmsskeyGenerate(...) SCTEST_CALL_SCIMPFN(SymCryptXmsskeyGenerate, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmsskeyGetValue(...) SCTEST_CALL_SCIMPFN(SymCryptXmsskeyGetValue, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmsskeySetValue(...) SCTEST_CALL_SCIMPFN(SymCryptXmsskeySetValue, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmssSizeofKeyBlobFromParams(...) SCTEST_CALL_SCIMPFN(SymCryptXmssSizeofKeyBlobFromParams, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmssMtParamsFromAlgId(...) SCTEST_CALL_SCIMPFN(SymCryptXmssMtParamsFromAlgId, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmssParamsFromAlgId(...) SCTEST_CALL_SCIMPFN(SymCryptXmssParamsFromAlgId, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmssSetParams(...) SCTEST_CALL_SCIMPFN(SymCryptXmssSetParams, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmssSign(...) SCTEST_CALL_SCIMPFN(SymCryptXmssSign, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmssSizeofSignatureFromParams(...) SCTEST_CALL_SCIMPFN(SymCryptXmssSizeofSignatureFromParams, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmssVerify(...) SCTEST_CALL_SCIMPFN(SymCryptXmssVerify, __VA_ARGS__)
|
||||
#define ScShimSymCryptXmssSelftest(...) SCTEST_CALL_SCIMPFN(SymCryptXmssSelftest, __VA_ARGS__)
|
||||
|
||||
#define ScShimSymCryptMarvin32DefaultSeed SCTEST_GET_SCIMPSYM(SymCryptMarvin32DefaultSeed)
|
||||
#define ScShimSymCryptMd2Algorithm SCTEST_GET_SCIMPSYM(SymCryptMd2Algorithm)
|
||||
|
|
|
@ -418,3 +418,9 @@ public:
|
|||
PSYMCRYPT_DLGROUP pGroup;
|
||||
PSYMCRYPT_DLKEY pKey;
|
||||
};
|
||||
|
||||
template<>
|
||||
class XmssImpState<ImpXxx, AlgXmss> {
|
||||
public:
|
||||
PSYMCRYPT_XMSS_KEY pKey;
|
||||
};
|
|
@ -76,7 +76,7 @@ const SELFTEST_INFO g_selfTests[] =
|
|||
{&SymCryptSshKdfSha256SelfTest, "SshKdfSha256" },
|
||||
{&SymCryptSshKdfSha512SelfTest, "SshKdfSha512" },
|
||||
{&SymCryptSskdfSelfTest, "Sskdf" },
|
||||
|
||||
{&SymCryptXmssSelftest, "Xmss" },
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
|
|
|
@ -946,6 +946,11 @@ public:
|
|||
const static char * name;
|
||||
};
|
||||
|
||||
class AlgXmss {
|
||||
public:
|
||||
const static char * name;
|
||||
};
|
||||
|
||||
class AlgDeveloperTest{
|
||||
public:
|
||||
const static char * name;
|
||||
|
@ -1398,6 +1403,9 @@ testDsaAlgorithms();
|
|||
VOID
|
||||
testStatusIndicator(BOOL);
|
||||
|
||||
VOID
|
||||
testHbs();
|
||||
|
||||
KatData *
|
||||
getCustomResource( _In_ PSTR resourceName, _In_ PSTR resourceType );
|
||||
|
||||
|
@ -1847,6 +1855,17 @@ printXmmRegisters( PCSTR text );
|
|||
#define PERF_KEY_W22519 ( PERF_KEY_SW_TEST_CURVE | 32 )
|
||||
#define PERF_KEY_W448 ( PERF_KEY_SW_TEST_CURVE | 56 )
|
||||
|
||||
#define PERF_KEY_XMSS_SHA2_10_256 (SYMCRYPT_XMSS_SHA2_10_256)
|
||||
#define PERF_KEY_XMSS_SHA2_16_256 (SYMCRYPT_XMSS_SHA2_16_256)
|
||||
#define PERF_KEY_XMSS_SHA2_20_256 (SYMCRYPT_XMSS_SHA2_20_256)
|
||||
#define PERF_KEY_XMSS_SHA2_10_512 (SYMCRYPT_XMSS_SHA2_10_512)
|
||||
#define PERF_KEY_XMSS_SHA2_16_512 (SYMCRYPT_XMSS_SHA2_16_512)
|
||||
#define PERF_KEY_XMSS_SHA2_20_512 (SYMCRYPT_XMSS_SHA2_20_512)
|
||||
#define PERF_KEY_XMSS_SHAKE256_10_256 (SYMCRYPT_XMSS_SHAKE256_10_256)
|
||||
#define PERF_KEY_XMSS_SHAKE256_16_256 (SYMCRYPT_XMSS_SHAKE256_16_256)
|
||||
#define PERF_KEY_XMSS_SHAKE256_20_256 (SYMCRYPT_XMSS_SHAKE256_20_256)
|
||||
|
||||
|
||||
PCBYTE
|
||||
getPerfTestModulus( UINT32 exKeySize );
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -37,6 +37,7 @@ set(SOURCES
|
|||
perf.cpp
|
||||
testPaddingPkcs7.cpp
|
||||
testStatusIndicator.cpp
|
||||
testHbs.cpp
|
||||
)
|
||||
|
||||
# Append Windows-specific sources
|
||||
|
|
|
@ -246,6 +246,8 @@ const char * AlgEcdsaVerify::name = "EcdsaVerify";
|
|||
|
||||
const char * AlgEcdh::name = "Ecdh";
|
||||
|
||||
const char * AlgXmss::name = "Xmss";
|
||||
|
||||
const char * AlgDeveloperTest::name = "DeveloperTest";
|
||||
|
||||
const char * ModeEcb::name = "Ecb";
|
||||
|
@ -613,6 +615,7 @@ const char * g_algorithmNames[] = {
|
|||
AlgEcdsaSign::name,
|
||||
AlgEcdsaVerify::name,
|
||||
AlgEcdh::name,
|
||||
AlgXmss::name,
|
||||
|
||||
AlgDeveloperTest::name,
|
||||
NULL,
|
||||
|
@ -1533,6 +1536,8 @@ runFunctionalTests()
|
|||
|
||||
testEcc();
|
||||
|
||||
testHbs();
|
||||
|
||||
printSymCryptFipsGetSelftestsPerformed();
|
||||
|
||||
testStatusIndicator(g_printStatusIndicator);
|
||||
|
|
|
@ -276,6 +276,7 @@ const ALG_MEASURE_PARAMS g_algMeasureParams[] =
|
|||
"EcdsaVerify" , 1, {PERF_KEY_NIST192, PERF_KEY_NIST224, PERF_KEY_NIST256, PERF_KEY_NIST384, PERF_KEY_NIST521, PERF_KEY_NUMS256, PERF_KEY_NUMS384, PERF_KEY_NUMS512, PERF_KEY_W22519, PERF_KEY_W448,}, {},
|
||||
"Ecdh" , 1, {PERF_KEY_NIST192, PERF_KEY_NIST224, PERF_KEY_NIST256, PERF_KEY_NIST384, PERF_KEY_NIST521, PERF_KEY_NUMS256, PERF_KEY_NUMS384, PERF_KEY_NUMS512, PERF_KEY_W22519, PERF_KEY_W448, PERF_KEY_C255_19,}, {},
|
||||
"IEEE802_11SaeCustom" , 0, {}, {},
|
||||
"Xmss" , 1, { PERF_KEY_XMSS_SHA2_10_256, PERF_KEY_XMSS_SHA2_16_256, PERF_KEY_XMSS_SHA2_20_256, PERF_KEY_XMSS_SHA2_10_512, PERF_KEY_XMSS_SHAKE256_10_256 }, { PERF_DATASIZE_SAME_AS_KEYSIZE },
|
||||
|
||||
// Enable the line below if you are running perf on the developer test
|
||||
// "DeveloperTest" , 1, {1},{},
|
||||
|
@ -998,6 +999,23 @@ const struct {
|
|||
{ PERF_KEY_XTS_DATA_UNIT_4096, " 4k" },
|
||||
};
|
||||
|
||||
const struct {
|
||||
UINT32 algId;
|
||||
BOOL bMultitree;
|
||||
char* name;
|
||||
} g_XmssIdNameMappings[] = {
|
||||
{ SYMCRYPT_XMSS_SHA2_10_256, FALSE, "SHA2_10_256" },
|
||||
{ SYMCRYPT_XMSS_SHA2_16_256, FALSE, "SHA2_16_256" },
|
||||
{ SYMCRYPT_XMSS_SHA2_20_256, FALSE, "SHA2_20_256" },
|
||||
{ SYMCRYPT_XMSS_SHA2_10_512, FALSE, "SHA2_10_512" },
|
||||
{ SYMCRYPT_XMSS_SHA2_16_512, FALSE, "SHA2_16_512" },
|
||||
{ SYMCRYPT_XMSS_SHA2_20_512, FALSE, "SHA2_20_512" },
|
||||
{ SYMCRYPT_XMSS_SHAKE256_10_256, FALSE, "SHAKE256_10_256" },
|
||||
{ SYMCRYPT_XMSS_SHAKE256_16_256, FALSE, "SHAKE256_16_256" },
|
||||
{ SYMCRYPT_XMSS_SHAKE256_20_256, FALSE, "SHAKE256_20_256" },
|
||||
};
|
||||
|
||||
|
||||
VOID measurePerfOneAlg( AlgorithmImplementation * pAlgImp )
|
||||
{
|
||||
PerfDataFn dataFn = pAlgImp->m_perfDataFunction;
|
||||
|
@ -1063,15 +1081,27 @@ VOID measurePerfOneAlg( AlgorithmImplementation * pAlgImp )
|
|||
|
||||
perfInfo.strPostfix = "";
|
||||
|
||||
for( SIZE_T i=0; i < ARRAY_SIZE( g_exKeyParamMapping ); i++ )
|
||||
for (SIZE_T i = 0; i < ARRAY_SIZE(g_exKeyParamMapping); i++)
|
||||
{
|
||||
if( keyFlags == g_exKeyParamMapping[i].exKeyParam )
|
||||
if (keyFlags == g_exKeyParamMapping[i].exKeyParam)
|
||||
{
|
||||
perfInfo.strPostfix = g_exKeyParamMapping[i].str;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (STRICMP(pParams->algName, "Xmss") == 0)
|
||||
{
|
||||
for (SIZE_T i = 0; i < ARRAY_SIZE(g_XmssIdNameMappings); i++)
|
||||
{
|
||||
if (*k == g_XmssIdNameMappings[i].algId)
|
||||
{
|
||||
perfInfo.strPostfix = g_XmssIdNameMappings[i].name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( dataFn != NULL )
|
||||
{
|
||||
perfInfo.operationName = "";
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -90,6 +90,11 @@ template<class Implementation>
|
|||
void
|
||||
SetupSymCryptEckey( PBYTE buf1, PBYTE buf2, PBYTE buf3, UINT32 setRandomFlags );
|
||||
|
||||
template<class Implementation>
|
||||
void
|
||||
SetupSymCryptXmsskey( UINT32 algId );
|
||||
|
||||
|
||||
VOID
|
||||
trialDivisionSetFakePrime( PSYMCRYPT_TRIALDIVISION_PRIME p )
|
||||
{
|
||||
|
@ -345,6 +350,8 @@ addSymCryptImplementationToGlobalList()
|
|||
addImplementationToGlobalList<EccImp<ImpScVariant, AlgEcdsaVerify>>();
|
||||
addImplementationToGlobalList<EccImp<ImpScVariant, AlgEcdh>>();
|
||||
|
||||
addImplementationToGlobalList<XmssImp<ImpScVariant, AlgXmss>>();
|
||||
|
||||
#if SYMCRYPT_MS_VC
|
||||
addImplementationToGlobalList<ArithImp<ImpScVariant, AlgIEEE802_11SaeCustom>>();
|
||||
#endif
|
||||
|
|
|
@ -90,6 +90,7 @@ const SELFTEST_INFO g_selfTests_allocating[] =
|
|||
{&SymCryptDsaSelftest, "DSA" },
|
||||
{&SymCryptEcDsaSelftest, "ECDSA" },
|
||||
{&SymCryptRsaSelftest, "RSA" },
|
||||
{&SymCryptXmssSelftest, "Xmss" },
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
<ClCompile Include="testXof.cpp" />
|
||||
<ClCompile Include="testXts.cpp" />
|
||||
<ClCompile Include="testStatusIndicator.cpp" />
|
||||
<ClCompile Include="testHbs.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(Platform)'=='x64'">
|
||||
<MASM Include="amd64\savevectors.asm" />
|
||||
|
|
|
@ -0,0 +1,726 @@
|
|||
//
|
||||
// Test Hash-based Signatures
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
||||
//
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
extern
|
||||
"C"
|
||||
{
|
||||
VOID
|
||||
SYMCRYPT_CALL
|
||||
SymCryptHbsGetWinternitzLengths(
|
||||
UINT32 n, // blob size in bytes
|
||||
UINT32 w, // digit length in bits (Winternitz coefficient)
|
||||
_Out_ PUINT32 puLen1, // number of w-bit digits in n
|
||||
_Out_ PUINT32 puLen2 // number of w-bit digits to store the checksum <= len1 * (2^w - 1)
|
||||
);
|
||||
|
||||
UINT32
|
||||
SymCryptCountLeadingZeros32( UINT32 value );
|
||||
}
|
||||
|
||||
typedef struct _SYMCRYPT_WINTERNITZ_LENGTHS
|
||||
{
|
||||
UINT32 n;
|
||||
UINT32 w;
|
||||
UINT32 len1;
|
||||
UINT32 len2;
|
||||
} SYMCRYPT_WINTERNITZ_LENGTHS, * PSYMCRYPT_WINTERNITZ_LENGTHS;
|
||||
|
||||
//
|
||||
// Precomputed digit counts in Excel
|
||||
//
|
||||
// len1 = CEILING.MATH(8 * n / w)
|
||||
// len2 = FLOOR.MATH(LOG(len1 * (POWER(2, w) - 1), 2) / w) + 1
|
||||
//
|
||||
static const SYMCRYPT_WINTERNITZ_LENGTHS _SymCryptWinternitzLengths[] = {
|
||||
|
||||
// n w len1 len2
|
||||
{ 24, 1, 192, 8 },
|
||||
{ 24, 2, 96, 5 },
|
||||
{ 24, 3, 64, 3 },
|
||||
{ 24, 4, 48, 3 },
|
||||
{ 24, 5, 39, 3 },
|
||||
{ 24, 6, 32, 2 },
|
||||
{ 24, 7, 28, 2 },
|
||||
{ 24, 8, 24, 2 },
|
||||
|
||||
{ 32, 1, 256, 9 },
|
||||
{ 32, 2, 128, 5 },
|
||||
{ 32, 3, 86, 4 },
|
||||
{ 32, 4, 64, 3 },
|
||||
{ 32, 5, 52, 3 },
|
||||
{ 32, 6, 43, 2 },
|
||||
{ 32, 7, 37, 2 },
|
||||
{ 32, 8, 32, 2 },
|
||||
|
||||
{ 64, 1, 512, 10 },
|
||||
{ 64, 2, 256, 5 },
|
||||
{ 64, 3, 171, 4 },
|
||||
{ 64, 4, 128, 3 },
|
||||
{ 64, 5, 103, 3 },
|
||||
{ 64, 6, 86, 3 },
|
||||
{ 64, 7, 74, 2 },
|
||||
{ 64, 8, 64, 2 },
|
||||
};
|
||||
|
||||
VOID
|
||||
testWinternitzLengths()
|
||||
{
|
||||
for (UINT32 i = 0; i < sizeof(_SymCryptWinternitzLengths) / sizeof(_SymCryptWinternitzLengths[0]); i++)
|
||||
{
|
||||
UINT32 len1, len2;
|
||||
|
||||
SymCryptHbsGetWinternitzLengths(
|
||||
_SymCryptWinternitzLengths[i].n,
|
||||
_SymCryptWinternitzLengths[i].w,
|
||||
&len1,
|
||||
&len2);
|
||||
|
||||
CHECK4( len1 == _SymCryptWinternitzLengths[i].len1,
|
||||
"Incorrect Winternitz digit count for len1: expecting %d got %d",
|
||||
_SymCryptWinternitzLengths[i].len1,
|
||||
len1);
|
||||
|
||||
CHECK4( len2 == _SymCryptWinternitzLengths[i].len2,
|
||||
"Incorrect Winternitz digit count for len2: expecting %d got %d",
|
||||
_SymCryptWinternitzLengths[i].len2,
|
||||
len2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class HbsMultiImp : public HbsImplementation
|
||||
{
|
||||
public:
|
||||
HbsMultiImp( String algName );
|
||||
virtual ~HbsMultiImp();
|
||||
|
||||
private:
|
||||
HbsMultiImp(const HbsMultiImp&);
|
||||
VOID operator=(const HbsMultiImp&);
|
||||
|
||||
public:
|
||||
|
||||
typedef std::vector<HbsImplementation*> HbsImpPtrVector;
|
||||
|
||||
HbsImpPtrVector m_imps; // Implementations we use
|
||||
|
||||
HbsImpPtrVector m_comps; // Subset of m_imps; set of ongoing computations
|
||||
|
||||
VOID addImplementation(HbsImplementation* pImp );
|
||||
VOID setImpName();
|
||||
|
||||
virtual NTSTATUS setKey(UINT32, BOOL, PCBYTE, SIZE_T, BOOL);
|
||||
virtual NTSTATUS sign(PCBYTE, SIZE_T, PBYTE, SIZE_T);
|
||||
virtual NTSTATUS verify(PCBYTE, SIZE_T, PCBYTE, SIZE_T);
|
||||
};
|
||||
|
||||
VOID
|
||||
HbsMultiImp::setImpName()
|
||||
{
|
||||
String sumAlgName;
|
||||
char* sepStr = "<";
|
||||
|
||||
for (HbsImpPtrVector::const_iterator i = m_imps.begin(); i != m_imps.end(); ++i)
|
||||
{
|
||||
sumAlgName += sepStr + (*i)->m_algorithmName;
|
||||
sepStr = "+";
|
||||
}
|
||||
m_implementationName = sumAlgName + ">";
|
||||
}
|
||||
|
||||
HbsMultiImp::HbsMultiImp(String algName)
|
||||
{
|
||||
m_algorithmName = algName;
|
||||
|
||||
getAllImplementations<HbsImplementation>(algName, &m_imps);
|
||||
}
|
||||
|
||||
VOID
|
||||
HbsMultiImp::addImplementation(HbsImplementation* pImp)
|
||||
{
|
||||
m_imps.push_back(pImp);
|
||||
setImpName();
|
||||
}
|
||||
|
||||
|
||||
HbsMultiImp::~HbsMultiImp()
|
||||
{
|
||||
//
|
||||
// Propagate the # KAT failures to the individual algorithms.
|
||||
//
|
||||
for (HbsImpPtrVector::iterator i = m_imps.begin(); i != m_imps.end(); ++i)
|
||||
{
|
||||
(*i)->m_nErrorKatFailure += m_nErrorKatFailure;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
HbsMultiImp::setKey(
|
||||
UINT32 uAlgId,
|
||||
BOOL fMultitree,
|
||||
PCBYTE pbSrc,
|
||||
SIZE_T cbSrc,
|
||||
BOOL fVerify )
|
||||
{
|
||||
m_comps.clear();
|
||||
|
||||
for (HbsImpPtrVector::const_iterator i = m_imps.begin(); i != m_imps.end(); ++i)
|
||||
{
|
||||
if ((*i)->setKey(uAlgId, fMultitree, pbSrc, cbSrc, fVerify) == STATUS_SUCCESS)
|
||||
{
|
||||
m_comps.push_back(*i);
|
||||
}
|
||||
}
|
||||
|
||||
return m_comps.size() == 0 ? STATUS_NOT_SUPPORTED : STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
HbsMultiImp::sign(
|
||||
PCBYTE pbMsg,
|
||||
SIZE_T cbMsg,
|
||||
PBYTE pbSignature,
|
||||
SIZE_T cbSignature )
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
ResultMerge res;
|
||||
PBYTE pbBuffer = NULL;
|
||||
|
||||
pbBuffer = new BYTE[cbSignature];
|
||||
|
||||
CHECK(pbBuffer != nullptr, "Memory allocation error");
|
||||
|
||||
for (HbsImpPtrVector::const_iterator i = m_comps.begin(); i != m_comps.end(); ++i)
|
||||
{
|
||||
SymCryptWipe(pbBuffer, cbSignature);
|
||||
if ((*i)->sign(pbMsg, cbMsg, pbBuffer, cbSignature) != STATUS_SUCCESS)
|
||||
{
|
||||
CHECK(FALSE, "Signature generation error");
|
||||
continue;
|
||||
}
|
||||
res.addResult((*i), pbBuffer, cbSignature);
|
||||
}
|
||||
|
||||
res.getResult(pbSignature, cbSignature);
|
||||
|
||||
delete[] pbBuffer;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
HbsMultiImp::verify(
|
||||
PCBYTE pbMsg,
|
||||
SIZE_T cbMsg,
|
||||
PCBYTE pbSignature,
|
||||
SIZE_T cbSignature )
|
||||
{
|
||||
NTSTATUS status = STATUS_SUCCESS;
|
||||
ResultMerge res;
|
||||
BYTE b[4];
|
||||
|
||||
for (HbsImpPtrVector::const_iterator i = m_comps.begin(); i != m_comps.end(); ++i)
|
||||
{
|
||||
status = (*i)->verify(pbMsg, cbMsg, pbSignature, cbSignature);
|
||||
SYMCRYPT_STORE_MSBFIRST32(b, status);
|
||||
res.addResult((*i), b, 4);
|
||||
}
|
||||
|
||||
res.getResult(b, 4);
|
||||
status = SYMCRYPT_LOAD_MSBFIRST32(b);
|
||||
return status;
|
||||
}
|
||||
|
||||
VOID
|
||||
testHbsVerify(
|
||||
HbsImplementation* pHbs,
|
||||
UINT32 AlgId,
|
||||
BOOL fMultitree,
|
||||
_In_reads_(cbMsg) PCBYTE pbMsg,
|
||||
SIZE_T cbMsg,
|
||||
_In_reads_(cbPubkey) PCBYTE pbPubkey,
|
||||
SIZE_T cbPubkey,
|
||||
_In_reads_(cbSig) PCBYTE pbSig,
|
||||
SIZE_T cbSig,
|
||||
LONGLONG line )
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
UNREFERENCED_PARAMETER(line);
|
||||
|
||||
status = pHbs->setKey(AlgId, fMultitree, pbPubkey, cbPubkey, FALSE);
|
||||
CHECK3(status == STATUS_SUCCESS, "Hbs setKey failed for algid = %u", AlgId);
|
||||
|
||||
status = pHbs->verify(pbMsg, cbMsg, pbSig, cbSig);
|
||||
CHECK3(status == STATUS_SUCCESS, "Hbs verify failed for algid = %u", AlgId);
|
||||
}
|
||||
|
||||
VOID
|
||||
testHbsSign(
|
||||
HbsImplementation* pHbs,
|
||||
UINT32 AlgId,
|
||||
BOOL fMultitree,
|
||||
_In_reads_(cbMsg) PCBYTE pbMsg,
|
||||
SIZE_T cbMsg,
|
||||
_In_reads_(cbPrvkey) PCBYTE pbPrvkey,
|
||||
SIZE_T cbPrvkey,
|
||||
_In_reads_(cbSig) PCBYTE pbSig,
|
||||
SIZE_T cbSig,
|
||||
LONGLONG line )
|
||||
{
|
||||
NTSTATUS status;
|
||||
PBYTE pbSig2 = nullptr;
|
||||
|
||||
UNREFERENCED_PARAMETER(line);
|
||||
|
||||
pbSig2 = new BYTE[cbSig];
|
||||
CHECK3(pbSig2 != nullptr, "Memory allocation failed for %u bytes", cbSig);
|
||||
|
||||
status = pHbs->setKey(AlgId, fMultitree, pbPrvkey, cbPrvkey, FALSE);
|
||||
CHECK3(status == STATUS_SUCCESS, "Hbs setKey failed for algid = %u", AlgId);
|
||||
|
||||
status = pHbs->sign(pbMsg, cbMsg, pbSig2, cbSig);
|
||||
CHECK3(status == STATUS_SUCCESS, "Hbs sign failed for algid = %u", AlgId);
|
||||
|
||||
int bMatch = memcmp(pbSig, pbSig2, cbSig) == 0;
|
||||
CHECK3(bMatch == TRUE, "generated signature does not match the given one for alg id %d", AlgId);
|
||||
|
||||
delete[] pbSig2;
|
||||
}
|
||||
|
||||
VOID
|
||||
testHbsKeygen(
|
||||
HbsImplementation* pHbs,
|
||||
UINT32 AlgId,
|
||||
BOOL fMultitree,
|
||||
_In_reads_(cbPrvkey) PCBYTE pbPrvkey,
|
||||
SIZE_T cbPrvkey,
|
||||
LONGLONG line )
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
||||
UNREFERENCED_PARAMETER(line);
|
||||
|
||||
status = pHbs->setKey(AlgId, fMultitree, pbPrvkey, cbPrvkey, TRUE);
|
||||
CHECK3(status == STATUS_SUCCESS, "Hbs setKey failed for algid = %u", AlgId);
|
||||
}
|
||||
|
||||
VOID
|
||||
testHbsKats()
|
||||
{
|
||||
KatData* katHbs = getCustomResource("kat_hbs.dat", "KAT_HBS");
|
||||
KAT_ITEM katItem;
|
||||
|
||||
static String g_currentCategory;
|
||||
BOOL skipData = TRUE;
|
||||
String sep = " ";
|
||||
BOOL doneAnything = FALSE;
|
||||
|
||||
std::unique_ptr<HbsMultiImp> pHbsMultiImp;
|
||||
|
||||
while (1)
|
||||
{
|
||||
katHbs->getKatItem(&katItem);
|
||||
|
||||
if (katItem.type == KAT_TYPE_END)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (katItem.type == KAT_TYPE_CATEGORY)
|
||||
{
|
||||
g_currentCategory = katItem.categoryName;
|
||||
|
||||
pHbsMultiImp.reset(new HbsMultiImp(g_currentCategory));
|
||||
|
||||
skipData = (pHbsMultiImp->m_imps.size() == 0);
|
||||
|
||||
if (!skipData)
|
||||
{
|
||||
iprint("%s%s", sep.c_str(), g_currentCategory.c_str());
|
||||
sep = ", ";
|
||||
doneAnything = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (skipData)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (katItem.type == KAT_TYPE_DATASET)
|
||||
{
|
||||
if (katIsFieldPresent(katItem, "pubkey"))
|
||||
{
|
||||
//
|
||||
// Signature verification test
|
||||
//
|
||||
BOOL fMultitree = FALSE;
|
||||
UINT32 nExpectedItems = 4;
|
||||
|
||||
if (katIsFieldPresent(katItem, "multitree"))
|
||||
{
|
||||
fMultitree = katParseInteger(katItem, "multitree") > 0;
|
||||
nExpectedItems++;
|
||||
}
|
||||
|
||||
CHECK3(katItem.dataItems.size() == nExpectedItems, "Incorrect number of items in Hbs signature verification record ending at line %lld", katHbs->m_line);
|
||||
|
||||
UINT32 algId = (UINT32)katParseInteger(katItem, "algid");
|
||||
BString katMsg = katParseData(katItem, "msg");
|
||||
BString katPubkey = katParseData(katItem, "pubkey");
|
||||
BString katSig = katParseData(katItem, "sig");
|
||||
|
||||
testHbsVerify(
|
||||
pHbsMultiImp.get(),
|
||||
algId,
|
||||
fMultitree,
|
||||
(PCBYTE)katMsg.data(),
|
||||
katMsg.size(),
|
||||
(PCBYTE)katPubkey.data(),
|
||||
katPubkey.size(),
|
||||
(PCBYTE)katSig.data(),
|
||||
katSig.size(),
|
||||
katHbs->m_line);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (katIsFieldPresent(katItem, "prvkey"))
|
||||
{
|
||||
if (katIsFieldPresent(katItem, "msg"))
|
||||
{
|
||||
//
|
||||
// Signature generation test
|
||||
//
|
||||
BOOL fMultitree = FALSE;
|
||||
UINT32 nExpectedItems = 4;
|
||||
|
||||
if (katIsFieldPresent(katItem, "multitree"))
|
||||
{
|
||||
fMultitree = katParseInteger(katItem, "multitree") > 0;
|
||||
nExpectedItems++;
|
||||
}
|
||||
|
||||
CHECK3(katItem.dataItems.size() == nExpectedItems, "Incorrect number of items in Hbs signature verification record ending at line %lld", katHbs->m_line);
|
||||
|
||||
UINT32 algId = (UINT32)katParseInteger(katItem, "algid");
|
||||
BString katMsg = katParseData(katItem, "msg");
|
||||
BString katPrvkey = katParseData(katItem, "prvkey");
|
||||
BString katSig = katParseData(katItem, "sig");
|
||||
|
||||
testHbsSign(
|
||||
pHbsMultiImp.get(),
|
||||
algId,
|
||||
fMultitree,
|
||||
(PCBYTE)katMsg.data(),
|
||||
katMsg.size(),
|
||||
(PCBYTE)katPrvkey.data(),
|
||||
katPrvkey.size(),
|
||||
(PCBYTE)katSig.data(),
|
||||
katSig.size(),
|
||||
katHbs->m_line);
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Key generation test
|
||||
//
|
||||
BOOL fMultitree = FALSE;
|
||||
UINT32 nExpectedItems = 2;
|
||||
|
||||
if (katIsFieldPresent(katItem, "multitree"))
|
||||
{
|
||||
fMultitree = katParseInteger(katItem, "multitree") > 0;
|
||||
nExpectedItems++;
|
||||
}
|
||||
|
||||
CHECK3(katItem.dataItems.size() == nExpectedItems, "Incorrect number of items in Hbs signature verification record ending at line %lld", katHbs->m_line);
|
||||
|
||||
UINT32 algId = (UINT32)katParseInteger(katItem, "algid");
|
||||
BString katPrvkey = katParseData(katItem, "prvkey");
|
||||
|
||||
testHbsKeygen(
|
||||
pHbsMultiImp.get(),
|
||||
algId,
|
||||
fMultitree,
|
||||
(PCBYTE)katPrvkey.data(),
|
||||
katPrvkey.size(),
|
||||
katHbs->m_line);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
FATAL2("Unknown data record ending at line %lld", katHbs->m_line);
|
||||
}
|
||||
}
|
||||
|
||||
if (doneAnything)
|
||||
{
|
||||
iprint("\n");
|
||||
}
|
||||
|
||||
delete katHbs;
|
||||
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
testXmssCustomParameters()
|
||||
{
|
||||
SYMCRYPT_XMSS_PARAMS params;
|
||||
PSYMCRYPT_XMSS_KEY pKey;
|
||||
PBYTE pbSignature;
|
||||
SYMCRYPT_ERROR scError;
|
||||
SIZE_T cbSignature;
|
||||
BYTE msg[] = { 0x00, 0x01, 0x03, 0x04 };
|
||||
PCSYMCRYPT_HASH pHash = SymCryptSha256Algorithm;
|
||||
|
||||
//
|
||||
// Test varying Winternitz lengths with custom tree heights
|
||||
//
|
||||
for (UINT8 w = 1; w <= 8; w <<= 1)
|
||||
{
|
||||
for (UINT8 h = 1; h <= 4; h++)
|
||||
{
|
||||
ScDispatchSymCryptWipe(¶ms, sizeof(SYMCRYPT_XMSS_PARAMS));
|
||||
|
||||
scError = ScDispatchSymCryptXmssSetParams(
|
||||
¶ms,
|
||||
0, // alg id
|
||||
pHash, // hash alg.
|
||||
(UINT8)pHash->resultSize, // n
|
||||
w, // w
|
||||
h, // h
|
||||
(UINT8)1, // d
|
||||
(UINT8)pHash->resultSize); // cbPrefix
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
pKey = ScDispatchSymCryptXmsskeyAllocate(¶ms, 0);
|
||||
CHECK(pKey != nullptr, "?");
|
||||
|
||||
scError = ScDispatchSymCryptXmsskeyGenerate(pKey, 0);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
cbSignature = ScDispatchSymCryptXmssSizeofSignatureFromParams(¶ms);
|
||||
pbSignature = new BYTE[cbSignature];
|
||||
CHECK(pbSignature != nullptr, "?");
|
||||
|
||||
// Sign and Verify with each WOTSP key
|
||||
for (UINT32 idx = 0; idx < (1UL << h); idx++)
|
||||
{
|
||||
scError = ScDispatchSymCryptXmssSign(pKey, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
scError = ScDispatchSymCryptXmssVerify(pKey, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
// Modify the signature and expect verification failure
|
||||
UINT32 nModifyPos = g_rng.uint32() % cbSignature;
|
||||
pbSignature[nModifyPos] ^= 1;
|
||||
|
||||
scError = ScDispatchSymCryptXmssVerify(pKey, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError != SYMCRYPT_NO_ERROR, "?");
|
||||
}
|
||||
|
||||
// All one-time signatures are consumed above, we shouldn't be able to sign anymore
|
||||
scError = ScDispatchSymCryptXmssSign(pKey, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError == SYMCRYPT_HBS_NO_OTS_KEYS_LEFT, "?");
|
||||
|
||||
delete[] pbSignature;
|
||||
|
||||
ScDispatchSymCryptXmsskeyFree(pKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
testXmssImportExport()
|
||||
{
|
||||
SYMCRYPT_XMSS_PARAMS params;
|
||||
PSYMCRYPT_XMSS_KEY pKeyPrivate;
|
||||
PSYMCRYPT_XMSS_KEY pKeyPublic;
|
||||
SYMCRYPT_ERROR scError;
|
||||
PBYTE pbPrivateKeyBlob;
|
||||
PBYTE pbPublicKeyBlob;
|
||||
SIZE_T cbPrivateKey;
|
||||
SIZE_T cbPublicKey;
|
||||
PBYTE pbSignature;
|
||||
PBYTE pbSignature2;
|
||||
SIZE_T cbSignature;
|
||||
BYTE msg[] = { 0x01 };
|
||||
|
||||
scError = ScDispatchSymCryptXmssParamsFromAlgId(SYMCRYPT_XMSS_SHA2_10_256, ¶ms);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
// Create a private key
|
||||
pKeyPrivate = ScDispatchSymCryptXmsskeyAllocate(¶ms, 0);
|
||||
CHECK(pKeyPrivate != nullptr, "?");
|
||||
scError = ScDispatchSymCryptXmsskeyGenerate(pKeyPrivate, 0);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
scError = ScDispatchSymCryptXmssSizeofKeyBlobFromParams(¶ms, SYMCRYPT_XMSSKEY_TYPE_PUBLIC, &cbPublicKey);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
scError = ScDispatchSymCryptXmssSizeofKeyBlobFromParams(¶ms, SYMCRYPT_XMSSKEY_TYPE_PRIVATE, &cbPrivateKey);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
// Export private key
|
||||
pbPrivateKeyBlob = new BYTE[cbPrivateKey];
|
||||
CHECK(pbPrivateKeyBlob != nullptr, "?");
|
||||
scError = ScDispatchSymCryptXmsskeyGetValue(pKeyPrivate, SYMCRYPT_XMSSKEY_TYPE_PRIVATE, 0, pbPrivateKeyBlob, cbPrivateKey);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
// Export public key
|
||||
pbPublicKeyBlob = new BYTE[cbPublicKey];
|
||||
CHECK(pbPublicKeyBlob != nullptr, "?");
|
||||
scError = ScDispatchSymCryptXmsskeyGetValue(pKeyPrivate, SYMCRYPT_XMSSKEY_TYPE_PUBLIC, 0, pbPublicKeyBlob, cbPublicKey);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
// Sign and verify a message
|
||||
cbSignature = ScDispatchSymCryptXmssSizeofSignatureFromParams(¶ms);
|
||||
pbSignature = new BYTE[cbSignature];
|
||||
CHECK(pbSignature != nullptr, "?");
|
||||
|
||||
scError = ScDispatchSymCryptXmssSign(pKeyPrivate, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
scError = ScDispatchSymCryptXmssVerify(pKeyPrivate, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
// Done with the original private key
|
||||
ScDispatchSymCryptXmsskeyFree(pKeyPrivate);
|
||||
|
||||
// Import the private key from the key blob
|
||||
pKeyPrivate = ScDispatchSymCryptXmsskeyAllocate(¶ms, 0);
|
||||
CHECK(pKeyPrivate != nullptr, "?");
|
||||
scError = ScDispatchSymCryptXmsskeySetValue(pbPrivateKeyBlob, cbPrivateKey, SYMCRYPT_XMSSKEY_TYPE_PRIVATE, 0, pKeyPrivate);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
// Sign the message again with the imported private key and check if the same signature is produced
|
||||
pbSignature2 = new BYTE[cbSignature];
|
||||
CHECK(pbSignature2 != nullptr, "?");
|
||||
|
||||
scError = ScDispatchSymCryptXmssSign(pKeyPrivate, msg, sizeof(msg), 0, pbSignature2, cbSignature);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
CHECK(memcmp(pbSignature, pbSignature2, cbSignature) == 0, "?");
|
||||
|
||||
ScDispatchSymCryptXmsskeyFree(pKeyPrivate);
|
||||
|
||||
// Import the public key and verify the signature
|
||||
pKeyPublic = ScDispatchSymCryptXmsskeyAllocate(¶ms, 0);
|
||||
CHECK(pKeyPublic != nullptr, "?");
|
||||
scError = ScDispatchSymCryptXmsskeySetValue(pbPublicKeyBlob, cbPublicKey, SYMCRYPT_XMSSKEY_TYPE_PUBLIC, 0, pKeyPublic);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
scError = ScDispatchSymCryptXmssVerify(pKeyPublic, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
ScDispatchSymCryptXmsskeyFree(pKeyPublic);
|
||||
|
||||
delete[] pbSignature2;
|
||||
delete[] pbSignature;
|
||||
delete[] pbPublicKeyBlob;
|
||||
delete[] pbPrivateKeyBlob;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
testXmssMultitree()
|
||||
{
|
||||
SYMCRYPT_XMSS_PARAMS params;
|
||||
PSYMCRYPT_XMSS_KEY pKey;
|
||||
PBYTE pbSignature;
|
||||
SYMCRYPT_ERROR scError;
|
||||
SIZE_T cbSignature;
|
||||
BYTE msg[] = { 0x00, 0x01, 0x03, 0x04 };
|
||||
PCSYMCRYPT_HASH pHash = SymCryptSha256Algorithm;
|
||||
const UINT8 H = 6;
|
||||
const UINT8 LayerHeights[] = { 1, 2, 3 };
|
||||
|
||||
//
|
||||
// Total tree height is 6
|
||||
//
|
||||
// Test all possible layer heights 1, 2, 3, corresponding to
|
||||
// number of layers 6, 3, 2.
|
||||
//
|
||||
|
||||
for (UINT32 i = 0; i < sizeof(LayerHeights); i++)
|
||||
{
|
||||
scError = ScDispatchSymCryptXmssSetParams(
|
||||
¶ms,
|
||||
0,
|
||||
pHash,
|
||||
(UINT8)pHash->resultSize,
|
||||
(UINT8)4,
|
||||
H,
|
||||
(UINT8)(H / LayerHeights[i]),
|
||||
(UINT8)pHash->resultSize);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
pKey = ScDispatchSymCryptXmsskeyAllocate(¶ms, 0);
|
||||
CHECK(pKey != nullptr, "?");
|
||||
|
||||
scError = ScDispatchSymCryptXmsskeyGenerate(pKey, 0);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
cbSignature = ScDispatchSymCryptXmssSizeofSignatureFromParams(¶ms);
|
||||
pbSignature = new BYTE[cbSignature];
|
||||
CHECK(pbSignature != nullptr, "?");
|
||||
|
||||
// Sign and Verify with each WOTSP key
|
||||
for (UINT32 idx = 0; idx < (1UL << H); idx++)
|
||||
{
|
||||
scError = ScDispatchSymCryptXmssSign(pKey, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
scError = ScDispatchSymCryptXmssVerify(pKey, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError == SYMCRYPT_NO_ERROR, "?");
|
||||
|
||||
// Modify the signature and expect verification failure
|
||||
UINT32 nModifyPos = g_rng.uint32() % cbSignature;
|
||||
pbSignature[nModifyPos] ^= 1;
|
||||
|
||||
scError = ScDispatchSymCryptXmssVerify(pKey, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError != SYMCRYPT_NO_ERROR, "?");
|
||||
}
|
||||
|
||||
// All one-time signatures are consumed above, we shouldn't be able to sign anymore
|
||||
scError = ScDispatchSymCryptXmssSign(pKey, msg, sizeof(msg), 0, pbSignature, cbSignature);
|
||||
CHECK(scError == SYMCRYPT_HBS_NO_OTS_KEYS_LEFT , "?");
|
||||
|
||||
ScDispatchSymCryptXmsskeyFree(pKey);
|
||||
|
||||
delete[] pbSignature;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
testXmss()
|
||||
{
|
||||
testWinternitzLengths();
|
||||
|
||||
testXmssCustomParameters();
|
||||
|
||||
testXmssMultitree();
|
||||
|
||||
testXmssImportExport();
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
testHbs()
|
||||
{
|
||||
testXmss();
|
||||
|
||||
testHbsKats();
|
||||
}
|
|
@ -681,3 +681,16 @@ EXPORTS
|
|||
SymCrypt802_11SaeCustomDestroy
|
||||
SymCryptFipsGetSelftestsPerformed
|
||||
SymCryptDeprecatedStatusIndicator
|
||||
SymCryptXmsskeyAllocate
|
||||
SymCryptXmsskeyFree
|
||||
SymCryptXmsskeyGenerate
|
||||
SymCryptXmsskeyGetValue
|
||||
SymCryptXmsskeySetValue
|
||||
SymCryptXmssSizeofKeyBlobFromParams
|
||||
SymCryptXmssMtParamsFromAlgId
|
||||
SymCryptXmssParamsFromAlgId
|
||||
SymCryptXmssSetParams
|
||||
SymCryptXmssSign
|
||||
SymCryptXmssSizeofSignatureFromParams
|
||||
SymCryptXmssVerify
|
||||
SymCryptXmssSelftest
|
|
@ -21,6 +21,6 @@ kat_rsaSign.dat KAT_RSA_SIGN "..\kat_rsaSign.
|
|||
kat_rsaEnc.dat KAT_RSA_ENC "..\kat_rsaEnc.dat"
|
||||
kat_dh.dat KAT_DH "..\kat_dh.dat"
|
||||
kat_dsa.dat KAT_DSA "..\kat_dsa.dat"
|
||||
|
||||
kat_hbs.dat KAT_HBS "..\kat_hbs.dat"
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче