Merged PR 11324214: FIPS 140-3 CASTs for RSA, DSA, ECDSA

This change adds additional Cryptographic Algorithm Self-Tests (CASTs) for RSA, DSA and ECDSA. as required by FIPS 140-3. Specifically, it adds explicit Known Answer Tests (KATs), as the Pairwise Consistency Tests (PCTs) that we were using previously are no longer considered sufficient for CASTs.

Also adds pairwise consistency tests on key import for RSA and DSA, per recent changes in the FIPS 140-3 implementation guidance. ECDSA PCTs continue to be run prior to signing or key export, as a performance optimization. ECDH and DH do not have explicit PCTs, but they include the required checks specified in SP 800-56A rev 3.

Related work items: #53481333
This commit is contained in:
Mitch Lindgren 🦎 2024-08-30 05:26:38 +00:00
Родитель 6173477557
Коммит 3b4cad7a6a
11 изменённых файлов: 324 добавлений и 140 удалений

Просмотреть файл

@ -27,4 +27,9 @@ This is a potentially ABI-breaking change on Windows x86.
This is for consistency with the Semantic Versioning specification, as well as various tooling. This is for consistency with the Semantic Versioning specification, as well as various tooling.
### extern variables defined in SymCrypt headers will be removed and replaced by equivalent getter functions ### extern variables defined in SymCrypt headers will be removed and replaced by equivalent getter functions
This simplifies how we define dynamic module exports in a cross-platform way. This simplifies how we define dynamic module exports in a cross-platform way.
### Self-test functions and definitions will no longer be exposed/exported
Various functions and definitions related to FIPS self-tests are exposed to callers in
symcrypt_internal.h, and exported from the shared object libraries/DLLs. These functions are only
intended to be used internally for FIPS compliance, so they will be removed from external visibility.

Просмотреть файл

@ -7367,7 +7367,7 @@ SymCryptDlkeyExtendKeyUsage(
// Enable an existing key which has been generated or imported to be used in specified algorithms. // Enable an existing key which has been generated or imported to be used in specified algorithms.
// Some callers may not know at key generation or import time what algorithms a key will be used for // Some callers may not know at key generation or import time what algorithms a key will be used for
// and this API allows the key to be extended for use in additional algorithms. Use of this API may // and this API allows the key to be extended for use in additional algorithms. Use of this API may
// not be compliant with FIPS 140-3 // not be compliant with FIPS 140-3.
// //
// - flags must be some bitwise OR of the following flags: // - flags must be some bitwise OR of the following flags:
// SYMCRYPT_FLAG_DLKEY_DSA // SYMCRYPT_FLAG_DLKEY_DSA

Просмотреть файл

@ -2417,7 +2417,7 @@ typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_RSAKEY {
UINT32 fAlgorithmInfo; // Tracks which algorithms the key can be used in UINT32 fAlgorithmInfo; // Tracks which algorithms the key can be used in
// Also tracks which per-key selftests have been performed on this key // Also tracks which per-key selftests have been performed on this key
// A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_RSAKEY_*, and // A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_RSAKEY_*, and
// SYMCRYPT_SELFTEST_KEY_* values // SYMCRYPT_PCT_* values
UINT32 cbTotalSize; // Total size of the rsa key UINT32 cbTotalSize; // Total size of the rsa key
BOOLEAN hasPrivateKey; // Set to true if there is private key information set BOOLEAN hasPrivateKey; // Set to true if there is private key information set
@ -2571,7 +2571,7 @@ typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_DLKEY {
UINT32 fAlgorithmInfo; // Tracks which algorithms the key can be used in UINT32 fAlgorithmInfo; // Tracks which algorithms the key can be used in
// Also tracks which per-key selftests have been performed on this key // Also tracks which per-key selftests have been performed on this key
// A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_DLKEY_*, and // A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_DLKEY_*, and
// SYMCRYPT_SELFTEST_KEY_* values // SYMCRYPT_PCT_* values
BOOLEAN fHasPrivateKey; // Set to true if there is a private key set BOOLEAN fHasPrivateKey; // Set to true if there is a private key set
BOOLEAN fPrivateModQ; // Set to true if the private key is at most Q-1, otherwise it is at most P-2 BOOLEAN fPrivateModQ; // Set to true if the private key is at most Q-1, otherwise it is at most P-2
@ -2760,7 +2760,7 @@ typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_ECKEY {
UINT32 fAlgorithmInfo; // Tracks which algorithms the key can be used in UINT32 fAlgorithmInfo; // Tracks which algorithms the key can be used in
// Also tracks which per-key selftests have been performed on this key // Also tracks which per-key selftests have been performed on this key
// A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_ECKEY_*, and // A bitwise OR of SYMCRYPT_FLAG_KEY_*, SYMCRYPT_FLAG_ECKEY_*, and
// SYMCRYPT_SELFTEST_KEY_* values // SYMCRYPT_PCT_* values
BOOLEAN hasPrivateKey; // Set to true if there is a private key set BOOLEAN hasPrivateKey; // Set to true if there is a private key set
PCSYMCRYPT_ECURVE pCurve; // Handle to the curve which created the key PCSYMCRYPT_ECURVE pCurve; // Handle to the curve which created the key
@ -3130,18 +3130,25 @@ SymCryptFipsGetSelftestsPerformed(void);
// defer running expensive tests until we know they are required (e.g. if we generate an Eckey which // defer running expensive tests until we know they are required (e.g. if we generate an Eckey which
// may be used in ECDH or ECDSA, and only use it for ECDH, the ECDSA PCT is deferred until we first // may be used in ECDH or ECDSA, and only use it for ECDH, the ECDSA PCT is deferred until we first
// attempt to use the key in ECDSA, or export the private key). // attempt to use the key in ECDSA, or export the private key).
//
// For clarity, SYMCRYPT_PCT_* should be used instead of SYMCRYPT_SELFTEST_KEY_* going forward.
// The latter is retained for compatibility with existing code, but may be removed in a future
// breaking change.
// Dlkey selftest flags // Dlkey selftest flags
// DSA Pairwise Consistency Test to be run generated keys // DSA Pairwise Consistency Test to be run generated keys
#define SYMCRYPT_SELFTEST_KEY_DSA (0x1) #define SYMCRYPT_SELFTEST_KEY_DSA (0x1)
#define SYMCRYPT_PCT_DSA SYMCRYPT_SELFTEST_KEY_DSA
// Eckey selftest flags // Eckey selftest flags
// ECDSA Pairwise Consistency Test to be run generated keys // ECDSA Pairwise Consistency Test to be run generated keys
#define SYMCRYPT_SELFTEST_KEY_ECDSA (0x1) #define SYMCRYPT_SELFTEST_KEY_ECDSA (0x1)
#define SYMCRYPT_PCT_ECDSA SYMCRYPT_SELFTEST_KEY_ECDSA
// Rsakey selftest flags // Rsakey selftest flags
// RSA Pairwise Consistency Test to be run generated keys // RSA Pairwise Consistency Test to be run generated keys
#define SYMCRYPT_SELFTEST_KEY_RSA_SIGN (0x1) #define SYMCRYPT_SELFTEST_KEY_RSA_SIGN (0x1)
#define SYMCRYPT_PCT_RSA_SIGN SYMCRYPT_SELFTEST_KEY_RSA_SIGN
UINT32 UINT32
SYMCRYPT_CALL SYMCRYPT_CALL

Просмотреть файл

@ -480,12 +480,16 @@ SymCryptDlkeyGenerate(
{ {
if( ( flags & SYMCRYPT_FLAG_DLKEY_DSA ) != 0 ) if( ( flags & SYMCRYPT_FLAG_DLKEY_DSA ) != 0 )
{ {
// Ensure DSA algorithm selftest is run before first use of DSA algorithm
SYMCRYPT_RUN_SELFTEST_ONCE(
SymCryptDsaSelftest,
SYMCRYPT_SELFTEST_ALGORITHM_DSA );
// Run PCT eagerly as the key can only be used for DSA - there is no value in deferring // Run PCT eagerly as the key can only be used for DSA - there is no value in deferring
SYMCRYPT_RUN_KEYGEN_PCT( SYMCRYPT_RUN_KEY_PCT(
SymCryptDsaSignVerifyTest, SymCryptDsaPct,
pkDlkey, pkDlkey,
SYMCRYPT_SELFTEST_ALGORITHM_DSA, SYMCRYPT_PCT_DSA );
SYMCRYPT_SELFTEST_KEY_DSA );
} }
if( ( flags & SYMCRYPT_FLAG_DLKEY_DH ) != 0 ) if( ( flags & SYMCRYPT_FLAG_DLKEY_DH ) != 0 )
@ -796,8 +800,10 @@ SymCryptDlkeySetValue(
if( pkDlkey->fHasPrivateKey ) if( pkDlkey->fHasPrivateKey )
{ {
// We do not need to run a DSA PCT on import, indicate that the test has been run SYMCRYPT_RUN_KEY_PCT(
pkDlkey->fAlgorithmInfo |= SYMCRYPT_SELFTEST_KEY_DSA; SymCryptDsaPct,
pkDlkey,
SYMCRYPT_PCT_DSA );
} }
} }

Просмотреть файл

@ -418,11 +418,10 @@ SymCryptEcDsaSign(
} }
// If the key was generated and a PCT has not yet been performed - perform PCT before first use // If the key was generated and a PCT has not yet been performed - perform PCT before first use
SYMCRYPT_RUN_KEYGEN_PCT( SYMCRYPT_RUN_KEY_PCT(
SymCryptEcDsaSignVerifyTest, SymCryptEcDsaPct,
pKey, pKey,
SYMCRYPT_SELFTEST_ALGORITHM_ECDSA, SYMCRYPT_PCT_ECDSA );
SYMCRYPT_SELFTEST_KEY_ECDSA );
return SymCryptEcDsaSignEx( pKey, pbHashValue, cbHashValue, NULL, format, flags, pbSignature, cbSignature ); return SymCryptEcDsaSignEx( pKey, pbHashValue, cbHashValue, NULL, format, flags, pbSignature, cbSignature );
} }

Просмотреть файл

@ -547,11 +547,8 @@ SymCryptEckeySetValue(
SymCryptEcDsaSelftest, SymCryptEcDsaSelftest,
SYMCRYPT_SELFTEST_ALGORITHM_ECDSA ); SYMCRYPT_SELFTEST_ALGORITHM_ECDSA );
if( pEckey->hasPrivateKey ) // ECDSA PCT is deferred until the key is used or exported - see SymCryptEcDsaSign and
{ // SymCryptEckeyGetValue
// We do not need to run an ECDSA PCT on import, indicate that the test has been run
pEckey->fAlgorithmInfo |= SYMCRYPT_SELFTEST_KEY_ECDSA;
}
} }
if ( ( flags & SYMCRYPT_FLAG_ECKEY_ECDH ) != 0 ) if ( ( flags & SYMCRYPT_FLAG_ECKEY_ECDH ) != 0 )
@ -658,11 +655,10 @@ SymCryptEckeyGetValue(
if ( ((pEckey->fAlgorithmInfo & SYMCRYPT_FLAG_ECKEY_ECDSA) != 0) && if ( ((pEckey->fAlgorithmInfo & SYMCRYPT_FLAG_ECKEY_ECDSA) != 0) &&
((pEckey->fAlgorithmInfo & SYMCRYPT_FLAG_KEY_NO_FIPS) == 0) ) ((pEckey->fAlgorithmInfo & SYMCRYPT_FLAG_KEY_NO_FIPS) == 0) )
{ {
SYMCRYPT_RUN_KEYGEN_PCT( SYMCRYPT_RUN_KEY_PCT(
SymCryptEcDsaSignVerifyTest, SymCryptEcDsaPct,
pEckey, pEckey,
SYMCRYPT_SELFTEST_ALGORITHM_ECDSA, SYMCRYPT_PCT_ECDSA );
SYMCRYPT_SELFTEST_KEY_ECDSA );
} }
// Copy the key into the temporary integer // Copy the key into the temporary integer

Просмотреть файл

@ -475,14 +475,34 @@ const SYMCRYPT_SELFTEST_RSAKEY_2048 rsakey =
} }
}; };
// RSA-2048 PKCS1 signature on rgbSha256Hash generated with rsakey
const BYTE rgbRsaPkcs1Sig[] = {
0x8c, 0x01, 0x48, 0x38, 0x1a, 0x8f, 0xa9, 0xae, 0x55, 0xa6, 0xad, 0x04, 0x5f, 0x78, 0x1a, 0xf5,
0xae, 0xf4, 0x09, 0x5d, 0x9c, 0x3a, 0xe2, 0x13, 0xf2, 0x04, 0xd8, 0x8a, 0xf7, 0x58, 0x4f, 0xe5,
0xb0, 0xcc, 0xea, 0xd8, 0xd0, 0xc4, 0x57, 0xd1, 0x9e, 0x61, 0xa8, 0x62, 0xb3, 0x39, 0x03, 0xf6,
0x13, 0x45, 0x6f, 0x88, 0x1a, 0x14, 0x33, 0x07, 0x20, 0x17, 0xab, 0xe1, 0x00, 0x93, 0x69, 0x03,
0x37, 0x69, 0xbb, 0x0e, 0x0f, 0x63, 0x57, 0xed, 0xb7, 0x56, 0x3a, 0x5d, 0xf1, 0x93, 0xd3, 0x76,
0x90, 0xf3, 0xed, 0x25, 0x6f, 0xc5, 0xc8, 0xcb, 0x1a, 0xd7, 0xce, 0x02, 0x80, 0x28, 0xa3, 0x5f,
0x02, 0x6b, 0xf1, 0xfa, 0x94, 0x08, 0xbb, 0x79, 0xfd, 0x51, 0x37, 0xf1, 0x48, 0xe9, 0x55, 0xaa,
0x0f, 0xb0, 0xaf, 0x5d, 0x5f, 0xe9, 0x28, 0x7f, 0xb2, 0x67, 0x96, 0x6d, 0x91, 0x7c, 0x98, 0x0d,
0x60, 0x27, 0xea, 0x62, 0xf5, 0x22, 0x60, 0x0a, 0xbd, 0xfe, 0x9d, 0xd5, 0x96, 0xa6, 0x02, 0xbb,
0x6c, 0x51, 0x36, 0x74, 0x92, 0x23, 0xb9, 0x4b, 0x87, 0xf4, 0xef, 0x2b, 0x00, 0x34, 0xe3, 0xfb,
0x10, 0x1b, 0xcc, 0xab, 0xc4, 0xe5, 0xda, 0x27, 0xf5, 0xf2, 0x55, 0x18, 0x65, 0x59, 0x8b, 0xed,
0x8e, 0x52, 0x78, 0x5a, 0xc7, 0x4b, 0x6b, 0x1b, 0x66, 0x67, 0xe6, 0xc0, 0xd7, 0x5a, 0x2a, 0xab,
0xce, 0x1d, 0xf2, 0xdf, 0x92, 0xe0, 0xdb, 0xf7, 0x34, 0xe3, 0x05, 0x10, 0xe4, 0x13, 0x7b, 0x29,
0x14, 0xa5, 0x41, 0xcb, 0x6e, 0x81, 0x33, 0xd0, 0xf9, 0x93, 0xa8, 0x85, 0xd1, 0xf4, 0xea, 0xfc,
0xaf, 0x5d, 0x7b, 0xc7, 0xf4, 0xff, 0x6c, 0x1e, 0x76, 0x18, 0xc6, 0x09, 0xe9, 0x8a, 0xa4, 0x57,
0xe6, 0x6b, 0x3e, 0x32, 0x36, 0xb4, 0xfd, 0x6a, 0xea, 0x87, 0xe0, 0xe6, 0x42, 0x3e, 0xdc, 0x58
};
// SHA256 hash for DSA, ECDSA, RSA sign/verify tests // SHA256 hash for DSA, ECDSA, RSA sign/verify tests
// Hashed from: { 0x61, 0x62, 0x63 } // Hashed from: { 0x61, 0x62, 0x63 }
const BYTE rgbSha256Hash[] = const BYTE rgbSha256Hash[] =
{ {
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea,
0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23,
0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad
}; };
@ -509,72 +529,123 @@ const BYTE rgbXmssSha2_10_192Signature[] =
0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03,
// Randomness // 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, 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 // 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, 0x2d, 0xaa, 0x55, 0xc6, 0xdb, 0xa4, 0x46, 0x83, 0xda, 0x62, 0xba, 0x67, 0x1a, 0xa2, 0x53, 0x4a,
0x92, 0x1c, 0x80, 0xb7, 0xe6, 0x58, 0x66, 0xf3, 0x5d, 0x01, 0xd7, 0x31, 0x70, 0x7e, 0x22, 0x04, 0x73, 0xb0, 0xaa, 0x7a, 0x64, 0xf9, 0xba, 0xf5, 0xbf, 0xf4, 0x0c, 0x4e, 0x8d, 0xa6, 0x3b, 0xdf, 0x92, 0x1c, 0x80, 0xb7, 0xe6, 0x58, 0x66, 0xf3,
0x37, 0x58, 0x98, 0x7e, 0x9c, 0x81, 0xd4, 0xa5, 0xe0, 0x2e, 0xed, 0x6b, 0x61, 0x57, 0xe5, 0x73, 0x80, 0x42, 0x79, 0xe2, 0x30, 0x9d, 0xa8, 0x9c, 0x5d, 0x01, 0xd7, 0x31, 0x70, 0x7e, 0x22, 0x04, 0x73, 0xb0, 0xaa, 0x7a, 0x64, 0xf9, 0xba, 0xf5,
0x0c, 0x10, 0x1f, 0xb9, 0xf5, 0xa0, 0x17, 0x0e, 0xa0, 0x99, 0xa4, 0xd8, 0x42, 0xea, 0x90, 0xa3, 0xb0, 0x20, 0x89, 0x02, 0x35, 0xfe, 0x86, 0x2e, 0x37, 0x58, 0x98, 0x7e, 0x9c, 0x81, 0xd4, 0xa5, 0xe0, 0x2e, 0xed, 0x6b, 0x61, 0x57, 0xe5, 0x73,
0x9a, 0x72, 0x41, 0x72, 0x77, 0xb6, 0xbd, 0x30, 0x05, 0xb0, 0xfa, 0xb4, 0x43, 0xc9, 0xfe, 0x54, 0x3f, 0x78, 0x83, 0x87, 0x1a, 0x10, 0xeb, 0x8a, 0x80, 0x42, 0x79, 0xe2, 0x30, 0x9d, 0xa8, 0x9c, 0x0c, 0x10, 0x1f, 0xb9, 0xf5, 0xa0, 0x17, 0x0e,
0xf3, 0xbe, 0x59, 0x67, 0x86, 0x26, 0x6e, 0xa2, 0xff, 0xaa, 0xb1, 0xa4, 0xb3, 0xcb, 0xfd, 0xe5, 0x31, 0xb3, 0xd4, 0x2a, 0x02, 0x5e, 0xea, 0xfb, 0xa0, 0x99, 0xa4, 0xd8, 0x42, 0xea, 0x90, 0xa3, 0xb0, 0x20, 0x89, 0x02, 0x35, 0xfe, 0x86, 0x2e,
0xea, 0x95, 0x70, 0xa2, 0x56, 0xe9, 0x9e, 0xd1, 0x84, 0x0b, 0xd4, 0xc8, 0xa3, 0xee, 0x46, 0x48, 0x96, 0x1f, 0x30, 0x7d, 0x86, 0x63, 0x47, 0x18, 0x9a, 0x72, 0x41, 0x72, 0x77, 0xb6, 0xbd, 0x30, 0x05, 0xb0, 0xfa, 0xb4, 0x43, 0xc9, 0xfe, 0x54,
0xb2, 0xe2, 0x3b, 0xe3, 0x89, 0x28, 0x5b, 0x6f, 0x5d, 0x2a, 0xe4, 0xe5, 0x3e, 0xb2, 0x2a, 0x97, 0x00, 0x04, 0xe7, 0xe3, 0x87, 0xa3, 0x6b, 0x73, 0x3f, 0x78, 0x83, 0x87, 0x1a, 0x10, 0xeb, 0x8a, 0xf3, 0xbe, 0x59, 0x67, 0x86, 0x26, 0x6e, 0xa2,
0xe3, 0xcd, 0x99, 0x5a, 0x8b, 0x93, 0x6a, 0x28, 0x53, 0x66, 0x5b, 0x21, 0x0b, 0x88, 0x2f, 0x01, 0x31, 0x37, 0x03, 0x21, 0xf9, 0xd6, 0x47, 0x99, 0xff, 0xaa, 0xb1, 0xa4, 0xb3, 0xcb, 0xfd, 0xe5, 0x31, 0xb3, 0xd4, 0x2a, 0x02, 0x5e, 0xea, 0xfb,
0x75, 0x81, 0x27, 0x7b, 0x24, 0xa4, 0x23, 0x32, 0x33, 0x6b, 0x3b, 0x8f, 0xe3, 0x5b, 0x38, 0xcc, 0xa5, 0x53, 0xb0, 0x15, 0xd3, 0xc8, 0x42, 0x75, 0xea, 0x95, 0x70, 0xa2, 0x56, 0xe9, 0x9e, 0xd1, 0x84, 0x0b, 0xd4, 0xc8, 0xa3, 0xee, 0x46, 0x48,
0x2d, 0x73, 0x5a, 0x80, 0x01, 0x10, 0x66, 0x48, 0xf6, 0x3e, 0x36, 0x84, 0xc8, 0xc0, 0x7a, 0xf6, 0xfb, 0xe1, 0xe8, 0x15, 0x3e, 0x9e, 0x0c, 0xd0, 0x96, 0x1f, 0x30, 0x7d, 0x86, 0x63, 0x47, 0x18, 0xb2, 0xe2, 0x3b, 0xe3, 0x89, 0x28, 0x5b, 0x6f,
0x0c, 0x45, 0x82, 0xa3, 0xfa, 0x8a, 0x0b, 0x6f, 0x84, 0x0b, 0x98, 0xf9, 0x58, 0x88, 0xb8, 0x13, 0xc7, 0xd7, 0x4e, 0x91, 0x89, 0x2f, 0xc0, 0x6f, 0x5d, 0x2a, 0xe4, 0xe5, 0x3e, 0xb2, 0x2a, 0x97, 0x00, 0x04, 0xe7, 0xe3, 0x87, 0xa3, 0x6b, 0x73,
0x00, 0xf1, 0x6d, 0x67, 0xea, 0xb8, 0xae, 0xbb, 0xa9, 0x12, 0xcb, 0xe6, 0x69, 0xd6, 0x0e, 0xb3, 0xfb, 0xa8, 0xb0, 0x42, 0x06, 0x64, 0x25, 0x07, 0xe3, 0xcd, 0x99, 0x5a, 0x8b, 0x93, 0x6a, 0x28, 0x53, 0x66, 0x5b, 0x21, 0x0b, 0x88, 0x2f, 0x01,
0xcc, 0xb7, 0xa8, 0x05, 0x51, 0xc2, 0x9f, 0xe9, 0xed, 0x59, 0xb9, 0xb0, 0x9d, 0x4c, 0x56, 0x8e, 0xc2, 0x48, 0xf6, 0x4a, 0x8b, 0x71, 0x90, 0xa1, 0x31, 0x37, 0x03, 0x21, 0xf9, 0xd6, 0x47, 0x99, 0x75, 0x81, 0x27, 0x7b, 0x24, 0xa4, 0x23, 0x32,
0x3c, 0xd2, 0xf5, 0xab, 0x74, 0xca, 0xaf, 0x1c, 0x31, 0xa6, 0x45, 0x30, 0x89, 0xb4, 0xe1, 0x4a, 0x82, 0x08, 0x75, 0x46, 0x16, 0xd8, 0x1e, 0x8a, 0x33, 0x6b, 0x3b, 0x8f, 0xe3, 0x5b, 0x38, 0xcc, 0xa5, 0x53, 0xb0, 0x15, 0xd3, 0xc8, 0x42, 0x75,
0x42, 0x6c, 0xa0, 0x63, 0x71, 0x41, 0x4f, 0x50, 0xa8, 0xa2, 0x61, 0xcf, 0xb7, 0xd7, 0x4d, 0x91, 0x55, 0xf2, 0xf2, 0xdf, 0xf6, 0xe2, 0xac, 0xb3, 0x2d, 0x73, 0x5a, 0x80, 0x01, 0x10, 0x66, 0x48, 0xf6, 0x3e, 0x36, 0x84, 0xc8, 0xc0, 0x7a, 0xf6,
0x6f, 0x54, 0x32, 0xb9, 0xf0, 0x3d, 0x8e, 0xf3, 0x04, 0xae, 0xdd, 0x8f, 0x53, 0xb9, 0x8b, 0xe3, 0xcc, 0x3d, 0xbc, 0x54, 0xe4, 0xc4, 0x7c, 0x6d, 0xfb, 0xe1, 0xe8, 0x15, 0x3e, 0x9e, 0x0c, 0xd0, 0x0c, 0x45, 0x82, 0xa3, 0xfa, 0x8a, 0x0b, 0x6f,
0x10, 0xfe, 0xd6, 0xeb, 0x12, 0xeb, 0xd1, 0xb1, 0x0a, 0x74, 0x56, 0x81, 0x3a, 0x05, 0x45, 0x65, 0x37, 0x0e, 0x8c, 0x0c, 0x0d, 0xad, 0x3e, 0x91, 0x84, 0x0b, 0x98, 0xf9, 0x58, 0x88, 0xb8, 0x13, 0xc7, 0xd7, 0x4e, 0x91, 0x89, 0x2f, 0xc0, 0x6f,
0xc7, 0x9a, 0x3c, 0xe6, 0xd7, 0x3a, 0xfb, 0x9f, 0x54, 0x66, 0x03, 0x0d, 0x9e, 0x18, 0xe5, 0xa2, 0x19, 0xca, 0x3a, 0xaa, 0x99, 0x6f, 0xe8, 0x15, 0x00, 0xf1, 0x6d, 0x67, 0xea, 0xb8, 0xae, 0xbb, 0xa9, 0x12, 0xcb, 0xe6, 0x69, 0xd6, 0x0e, 0xb3,
0xe3, 0x47, 0x4b, 0x90, 0x93, 0x17, 0x89, 0xda, 0x13, 0xff, 0xe5, 0xad, 0x8b, 0xd5, 0xe8, 0xeb, 0x25, 0x3e, 0x10, 0x66, 0x8e, 0x13, 0x01, 0x4d, 0xfb, 0xa8, 0xb0, 0x42, 0x06, 0x64, 0x25, 0x07, 0xcc, 0xb7, 0xa8, 0x05, 0x51, 0xc2, 0x9f, 0xe9,
0xc1, 0xc9, 0x17, 0x56, 0x4e, 0x23, 0xef, 0x34, 0x22, 0xed, 0x8d, 0x84, 0x7c, 0xd8, 0x42, 0x7b, 0x72, 0x3d, 0x45, 0x1f, 0x23, 0x60, 0x46, 0x1d, 0xed, 0x59, 0xb9, 0xb0, 0x9d, 0x4c, 0x56, 0x8e, 0xc2, 0x48, 0xf6, 0x4a, 0x8b, 0x71, 0x90, 0xa1,
0x60, 0xb4, 0xaf, 0x6d, 0xb9, 0xc3, 0xe3, 0xd4, 0x05, 0xee, 0x24, 0xb7, 0x1e, 0xbe, 0x37, 0x3d, 0x62, 0xc5, 0xe1, 0x6c, 0xd7, 0xc3, 0x43, 0xf4, 0x3c, 0xd2, 0xf5, 0xab, 0x74, 0xca, 0xaf, 0x1c, 0x31, 0xa6, 0x45, 0x30, 0x89, 0xb4, 0xe1, 0x4a,
0x1c, 0x8b, 0x95, 0xb8, 0x31, 0x0d, 0x6f, 0x51, 0x0b, 0xb8, 0xf0, 0x87, 0xf2, 0x94, 0x5c, 0x25, 0x2d, 0x84, 0x9a, 0x3b, 0x6b, 0x13, 0x61, 0xd6, 0x82, 0x08, 0x75, 0x46, 0x16, 0xd8, 0x1e, 0x8a, 0x42, 0x6c, 0xa0, 0x63, 0x71, 0x41, 0x4f, 0x50,
0x94, 0xa9, 0x53, 0x30, 0xd1, 0x00, 0x82, 0xb1, 0x04, 0x29, 0x78, 0x43, 0x60, 0x92, 0x39, 0xf0, 0x9a, 0xfe, 0xfb, 0x5c, 0x7c, 0x5e, 0x5e, 0x54, 0xa8, 0xa2, 0x61, 0xcf, 0xb7, 0xd7, 0x4d, 0x91, 0x55, 0xf2, 0xf2, 0xdf, 0xf6, 0xe2, 0xac, 0xb3,
0xcc, 0x9e, 0xf7, 0x67, 0x1c, 0x15, 0x6b, 0xa4, 0x5d, 0x90, 0xdd, 0x5c, 0x82, 0xef, 0x12, 0xca, 0x0f, 0x42, 0xc7, 0x54, 0x0b, 0xfb, 0x8a, 0xc5, 0x6f, 0x54, 0x32, 0xb9, 0xf0, 0x3d, 0x8e, 0xf3, 0x04, 0xae, 0xdd, 0x8f, 0x53, 0xb9, 0x8b, 0xe3,
0xfe, 0x6f, 0xdc, 0x95, 0x09, 0xd9, 0x7c, 0x19, 0xc6, 0x66, 0x8a, 0xff, 0x45, 0x2d, 0x59, 0xd1, 0x82, 0xdd, 0x56, 0xaa, 0x65, 0xf7, 0x37, 0x76, 0xcc, 0x3d, 0xbc, 0x54, 0xe4, 0xc4, 0x7c, 0x6d, 0x10, 0xfe, 0xd6, 0xeb, 0x12, 0xeb, 0xd1, 0xb1,
0x66, 0xc4, 0x4d, 0x70, 0x4b, 0xc8, 0x3f, 0x47, 0xc2, 0xe8, 0xd3, 0xb6, 0xe4, 0x4e, 0xa7, 0xc3, 0x0a, 0x29, 0x69, 0x57, 0xba, 0x64, 0x23, 0xd4, 0x0a, 0x74, 0x56, 0x81, 0x3a, 0x05, 0x45, 0x65, 0x37, 0x0e, 0x8c, 0x0c, 0x0d, 0xad, 0x3e, 0x91,
0x75, 0x74, 0x12, 0x85, 0xf8, 0x42, 0x1d, 0xc9, 0xd0, 0x65, 0x5a, 0x8f, 0xed, 0x49, 0xbb, 0x3d, 0x2e, 0xe5, 0xee, 0x14, 0x95, 0xc1, 0x92, 0xf6, 0xc7, 0x9a, 0x3c, 0xe6, 0xd7, 0x3a, 0xfb, 0x9f, 0x54, 0x66, 0x03, 0x0d, 0x9e, 0x18, 0xe5, 0xa2,
0xf7, 0xac, 0xe1, 0x07, 0x00, 0x6c, 0x9b, 0xd9, 0xa8, 0x41, 0x96, 0xdc, 0x8b, 0x07, 0x05, 0xb8, 0x16, 0x54, 0x34, 0x29, 0xf9, 0x3e, 0x5a, 0x86, 0x19, 0xca, 0x3a, 0xaa, 0x99, 0x6f, 0xe8, 0x15, 0xe3, 0x47, 0x4b, 0x90, 0x93, 0x17, 0x89, 0xda,
0x82, 0x93, 0xa2, 0x5f, 0xf8, 0x4b, 0x3c, 0x52, 0xf8, 0x5a, 0x62, 0x0e, 0x01, 0xe0, 0x26, 0xcd, 0x3b, 0x04, 0xa8, 0xe1, 0x00, 0xc9, 0x06, 0x16, 0x13, 0xff, 0xe5, 0xad, 0x8b, 0xd5, 0xe8, 0xeb, 0x25, 0x3e, 0x10, 0x66, 0x8e, 0x13, 0x01, 0x4d,
0x51, 0x79, 0xaa, 0xb4, 0x56, 0x44, 0x08, 0x20, 0x17, 0xc1, 0x2f, 0x17, 0xc5, 0x8c, 0xbb, 0xad, 0x8c, 0x28, 0x53, 0x29, 0x1c, 0xde, 0xf1, 0xa3, 0xc1, 0xc9, 0x17, 0x56, 0x4e, 0x23, 0xef, 0x34, 0x22, 0xed, 0x8d, 0x84, 0x7c, 0xd8, 0x42, 0x7b,
0xa1, 0x04, 0x1d, 0x01, 0x7f, 0xe5, 0xa8, 0xb2, 0xea, 0xb6, 0x4b, 0x7b, 0x3e, 0x3b, 0x50, 0x6b, 0x2a, 0x72, 0x5a, 0x5e, 0xd7, 0x9b, 0xf4, 0x16, 0x72, 0x3d, 0x45, 0x1f, 0x23, 0x60, 0x46, 0x1d, 0x60, 0xb4, 0xaf, 0x6d, 0xb9, 0xc3, 0xe3, 0xd4,
0x1f, 0xec, 0x18, 0x2f, 0xc7, 0xa0, 0xb2, 0xb5, 0x25, 0xd0, 0x34, 0x64, 0x89, 0x00, 0x00, 0x85, 0xab, 0x6e, 0x90, 0x31, 0x3f, 0x91, 0x59, 0x35, 0x05, 0xee, 0x24, 0xb7, 0x1e, 0xbe, 0x37, 0x3d, 0x62, 0xc5, 0xe1, 0x6c, 0xd7, 0xc3, 0x43, 0xf4,
0x5c, 0x88, 0x25, 0xe6, 0xc3, 0x79, 0xde, 0x27, 0x8a, 0xab, 0x40, 0x4f, 0x17, 0xba, 0x04, 0xc7, 0x1a, 0xd9, 0x36, 0x92, 0x9c, 0x6a, 0x3c, 0xc8, 0x1c, 0x8b, 0x95, 0xb8, 0x31, 0x0d, 0x6f, 0x51, 0x0b, 0xb8, 0xf0, 0x87, 0xf2, 0x94, 0x5c, 0x25,
0x28, 0x6b, 0x2d, 0x15, 0x86, 0x6c, 0xe4, 0x4d, 0x48, 0x70, 0xbb, 0x09, 0xeb, 0xa9, 0x69, 0xef, 0xff, 0xee, 0xed, 0xbf, 0x82, 0x61, 0xb3, 0x3d, 0x2d, 0x84, 0x9a, 0x3b, 0x6b, 0x13, 0x61, 0xd6, 0x94, 0xa9, 0x53, 0x30, 0xd1, 0x00, 0x82, 0xb1,
0x63, 0x70, 0xfb, 0x4c, 0x8c, 0x1d, 0xca, 0xf4, 0x6f, 0x10, 0x36, 0x3b, 0x00, 0x65, 0x0c, 0x40, 0x47, 0x4c, 0xbb, 0x9f, 0x7a, 0x53, 0x72, 0x91, 0x04, 0x29, 0x78, 0x43, 0x60, 0x92, 0x39, 0xf0, 0x9a, 0xfe, 0xfb, 0x5c, 0x7c, 0x5e, 0x5e, 0x54,
0x6d, 0x4a, 0xe0, 0xf4, 0x89, 0xeb, 0x53, 0x99, 0x1a, 0x1a, 0xf3, 0xee, 0xc3, 0x93, 0xc7, 0x30, 0x3f, 0x61, 0xb6, 0xab, 0x6f, 0x0a, 0xab, 0xa8, 0xcc, 0x9e, 0xf7, 0x67, 0x1c, 0x15, 0x6b, 0xa4, 0x5d, 0x90, 0xdd, 0x5c, 0x82, 0xef, 0x12, 0xca,
0xbf, 0x33, 0x69, 0x82, 0xda, 0x12, 0xc8, 0xab, 0x8f, 0x01, 0x84, 0x30, 0x51, 0xf3, 0x12, 0xc5, 0xe2, 0x1c, 0xb7, 0x63, 0xb8, 0x14, 0x33, 0x5f, 0x0f, 0x42, 0xc7, 0x54, 0x0b, 0xfb, 0x8a, 0xc5, 0xfe, 0x6f, 0xdc, 0x95, 0x09, 0xd9, 0x7c, 0x19,
0x7b, 0x9a, 0x68, 0x4f, 0x27, 0xf9, 0x40, 0xa0, 0xad, 0x23, 0xf5, 0xf2, 0xf4, 0x78, 0xc4, 0x93, 0x2d, 0xfc, 0xe8, 0xea, 0x5c, 0x00, 0x2a, 0x13, 0xc6, 0x66, 0x8a, 0xff, 0x45, 0x2d, 0x59, 0xd1, 0x82, 0xdd, 0x56, 0xaa, 0x65, 0xf7, 0x37, 0x76,
0x4f, 0x2b, 0x5b, 0x26, 0x39, 0x50, 0xaf, 0x52, 0x33, 0xdd, 0xcd, 0xf3, 0x86, 0x53, 0x8f, 0xc6, 0xfe, 0x87, 0x2e, 0x73, 0xab, 0x34, 0xcb, 0xd4, 0x66, 0xc4, 0x4d, 0x70, 0x4b, 0xc8, 0x3f, 0x47, 0xc2, 0xe8, 0xd3, 0xb6, 0xe4, 0x4e, 0xa7, 0xc3,
0xc8, 0x76, 0x9d, 0x00, 0xd7, 0x98, 0x5b, 0x85, 0x95, 0x75, 0xcd, 0xb0, 0x07, 0xa6, 0xaf, 0xa8, 0xf5, 0x58, 0x2e, 0xc8, 0xd0, 0x50, 0x7c, 0xc2, 0x0a, 0x29, 0x69, 0x57, 0xba, 0x64, 0x23, 0xd4, 0x75, 0x74, 0x12, 0x85, 0xf8, 0x42, 0x1d, 0xc9,
0x1e, 0x71, 0x86, 0x86, 0xdb, 0x72, 0xcc, 0x68, 0x78, 0x51, 0x6d, 0xe1, 0x13, 0xdc, 0x6c, 0x89, 0xa6, 0x4a, 0xf5, 0x43, 0xf3, 0x29, 0x31, 0xbe, 0xd0, 0x65, 0x5a, 0x8f, 0xed, 0x49, 0xbb, 0x3d, 0x2e, 0xe5, 0xee, 0x14, 0x95, 0xc1, 0x92, 0xf6,
0x16, 0xab, 0x8b, 0xdf, 0x52, 0x0a, 0xc1, 0x7d, 0x04, 0x57, 0x39, 0xbb, 0x9a, 0x8d, 0x64, 0x7f, 0xf1, 0x64, 0x9e, 0xfc, 0x12, 0x8b, 0x84, 0x85, 0xf7, 0xac, 0xe1, 0x07, 0x00, 0x6c, 0x9b, 0xd9, 0xa8, 0x41, 0x96, 0xdc, 0x8b, 0x07, 0x05, 0xb8,
0x5e, 0x93, 0x35, 0xa6, 0x18, 0xcb, 0xbb, 0x1f, 0x37, 0xda, 0xc2, 0x19, 0xa3, 0x6e, 0x31, 0x8a, 0xa5, 0x50, 0xea, 0x70, 0xe1, 0x72, 0x20, 0x35, 0x16, 0x54, 0x34, 0x29, 0xf9, 0x3e, 0x5a, 0x86, 0x82, 0x93, 0xa2, 0x5f, 0xf8, 0x4b, 0x3c, 0x52,
0x09, 0x47, 0xa3, 0xc8, 0xbc, 0x23, 0xdf, 0x9c, 0x26, 0x36, 0x1b, 0x5a, 0x1f, 0x5f, 0x33, 0x81, 0xd6, 0xbd, 0x94, 0x84, 0x06, 0x81, 0x80, 0x1a, 0xf8, 0x5a, 0x62, 0x0e, 0x01, 0xe0, 0x26, 0xcd, 0x3b, 0x04, 0xa8, 0xe1, 0x00, 0xc9, 0x06, 0x16,
0xbd, 0x01, 0x9f, 0x4c, 0x66, 0x79, 0xc1, 0x2f, 0x84, 0x3a, 0xbb, 0x30, 0x68, 0xce, 0xd3, 0x94, 0xec, 0x92, 0xee, 0xd2, 0xe5, 0x28, 0x3f, 0xdd, 0x51, 0x79, 0xaa, 0xb4, 0x56, 0x44, 0x08, 0x20, 0x17, 0xc1, 0x2f, 0x17, 0xc5, 0x8c, 0xbb, 0xad,
0x3f, 0xf1, 0x8d, 0x71, 0x5a, 0x56, 0xe3, 0x88, 0x2c, 0x6e, 0x6f, 0xd7, 0x41, 0x41, 0xa4, 0xa6, 0xcb, 0x38, 0xfd, 0x8e, 0x18, 0xde, 0x7c, 0xd2, 0x8c, 0x28, 0x53, 0x29, 0x1c, 0xde, 0xf1, 0xa3, 0xa1, 0x04, 0x1d, 0x01, 0x7f, 0xe5, 0xa8, 0xb2,
0x9d, 0xec, 0xae, 0xac, 0xce, 0x5b, 0x20, 0x6f, 0x43, 0x06, 0x70, 0x1b, 0x1a, 0x10, 0xfd, 0x1c, 0x24, 0x8a, 0x99, 0xa2, 0x6e, 0xde, 0x2c, 0xfe, 0xea, 0xb6, 0x4b, 0x7b, 0x3e, 0x3b, 0x50, 0x6b, 0x2a, 0x72, 0x5a, 0x5e, 0xd7, 0x9b, 0xf4, 0x16,
0xd2, 0x49, 0xe7, 0xa3, 0x4b, 0x76, 0x1a, 0xf1, 0xee, 0xee, 0xd3, 0xb5, 0x1c, 0xb1, 0xdc, 0x20, 0xe5, 0x5c, 0x8d, 0x83, 0xa6, 0xf8, 0x12, 0x2e, 0x1f, 0xec, 0x18, 0x2f, 0xc7, 0xa0, 0xb2, 0xb5, 0x25, 0xd0, 0x34, 0x64, 0x89, 0x00, 0x00, 0x85,
0x6c, 0x6a, 0x2e, 0x16, 0x23, 0xed, 0x3c, 0x96, 0x52, 0x9c, 0x51, 0x0f, 0x2d, 0xbe, 0x1b, 0x3d, 0x6a, 0xd2, 0xf5, 0x43, 0xde, 0x7a, 0x5c, 0x07, 0xab, 0x6e, 0x90, 0x31, 0x3f, 0x91, 0x59, 0x35, 0x5c, 0x88, 0x25, 0xe6, 0xc3, 0x79, 0xde, 0x27,
0x85, 0x42, 0x89, 0x49, 0xa6, 0x08, 0x82, 0x13, 0xcd, 0xa1, 0xd5, 0x7d, 0x86, 0x51, 0x9b, 0x20, 0x44, 0x59, 0x71, 0x24, 0x72, 0xcc, 0xf0, 0x69, 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 // 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, 0x51, 0x4f, 0x87, 0x42, 0xee, 0x41, 0x95, 0x4d, 0x7c, 0x77, 0x36, 0x33, 0x58, 0x8c, 0xaa, 0x8e,
0x5b, 0x42, 0xf1, 0x46, 0xcd, 0x85, 0x59, 0x18, 0x85, 0x48, 0xd3, 0x4c, 0xbe, 0xd6, 0xb3, 0x36, 0x3f, 0x1f, 0x2b, 0x30, 0x13, 0x87, 0x2b, 0xd5, 0x24, 0x53, 0xaf, 0x69, 0xdc, 0x0a, 0xd9, 0x62, 0x5b, 0x42, 0xf1, 0x46, 0xcd, 0x85, 0x59, 0x18,
0xcd, 0xb7, 0x6b, 0x19, 0x68, 0x16, 0x91, 0x25, 0xc2, 0x0e, 0xbe, 0xb6, 0xbb, 0x6d, 0xe1, 0x37, 0x4d, 0x4c, 0x0a, 0x80, 0x02, 0x01, 0xdd, 0xfb, 0x85, 0x48, 0xd3, 0x4c, 0xbe, 0xd6, 0xb3, 0x36, 0x3f, 0x1f, 0x2b, 0x30, 0x13, 0x87, 0x2b, 0xd5,
0x0e, 0xb3, 0xaa, 0xf9, 0x83, 0x0d, 0x44, 0x72, 0x64, 0x5b, 0xec, 0xbf, 0xe0, 0x98, 0xd7, 0x4f, 0x09, 0x85, 0xf9, 0x99, 0x88, 0x78, 0xa7, 0xad, 0xcd, 0xb7, 0x6b, 0x19, 0x68, 0x16, 0x91, 0x25, 0xc2, 0x0e, 0xbe, 0xb6, 0xbb, 0x6d, 0xe1, 0x37,
0x6b, 0xce, 0xa3, 0xa0, 0x74, 0x72, 0xe1, 0x3a, 0x39, 0x29, 0x3f, 0x1b, 0xcd, 0xfe, 0x60, 0x54, 0xf5, 0xdb, 0xa3, 0xd6, 0x21, 0xde, 0x8c, 0x6f, 0x4d, 0x4c, 0x0a, 0x80, 0x02, 0x01, 0xdd, 0xfb, 0x0e, 0xb3, 0xaa, 0xf9, 0x83, 0x0d, 0x44, 0x72,
0x33, 0x52, 0x0c, 0xfb, 0x61, 0x60, 0x88, 0xb3, 0x17, 0x8a, 0xe5, 0x4a, 0xaa, 0x5b, 0x64, 0x01, 0x33, 0x57, 0x46, 0x91, 0x61, 0x95, 0x93, 0x08, 0x64, 0x5b, 0xec, 0xbf, 0xe0, 0x98, 0xd7, 0x4f, 0x09, 0x85, 0xf9, 0x99, 0x88, 0x78, 0xa7, 0xad,
0xe8, 0x0d, 0xba, 0xda, 0x0c, 0xeb, 0x96, 0x7b, 0x73, 0xa5, 0x79, 0xe4, 0x0b, 0x93, 0x51, 0x28, 0xa3, 0x44, 0x76, 0x62, 0xe6, 0xbe, 0xca, 0x0e, 0x6b, 0xce, 0xa3, 0xa0, 0x74, 0x72, 0xe1, 0x3a, 0x39, 0x29, 0x3f, 0x1b, 0xcd, 0xfe, 0x60, 0x54,
0x37, 0x7b, 0xf6, 0xfb, 0xbd, 0x6c, 0xd7, 0x8f, 0xba, 0x75, 0xd5, 0x6b, 0xc1, 0xc2, 0x04, 0xfa, 0xf8, 0xe3, 0x07, 0x10, 0x6f, 0xb4, 0x97, 0xf1, 0xf5, 0xdb, 0xa3, 0xd6, 0x21, 0xde, 0x8c, 0x6f, 0x33, 0x52, 0x0c, 0xfb, 0x61, 0x60, 0x88, 0xb3,
0xd7, 0xa8, 0x83, 0xa9, 0x9f, 0x20, 0x9c, 0xfc, 0xa7, 0x45, 0x71, 0x36, 0xeb, 0x26, 0xc7, 0x1d, 0x8a, 0x3c, 0x66, 0x78, 0x02, 0xc5, 0x76, 0xa1, 0x17, 0x8a, 0xe5, 0x4a, 0xaa, 0x5b, 0x64, 0x01, 0x33, 0x57, 0x46, 0x91, 0x61, 0x95, 0x93, 0x08,
0xd5, 0xc2, 0x15, 0x86, 0x2e, 0x8a, 0x46, 0xde, 0x45, 0xcf, 0xaf, 0xdd, 0xe3, 0xbe, 0xb6, 0x5e, 0x88, 0x1f, 0x9e, 0x63, 0xa6, 0xca, 0x89, 0x8b, 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,
};
const BYTE rgbDsaKnownAnswerTestSignature[64] = {
0x93, 0xa5, 0xe2, 0x73, 0xd0, 0x00, 0xd4, 0x9a, 0x12, 0x24, 0x2f, 0x0f, 0xcf, 0x03, 0xe2, 0x10,
0x05, 0x47, 0xd8, 0x84, 0x09, 0x8c, 0xc4, 0xde, 0xed, 0x83, 0xac, 0x10, 0xa8, 0x46, 0x57, 0x31,
0x64, 0x65, 0xe3, 0x18, 0xa3, 0xbe, 0x99, 0x1d, 0x88, 0x06, 0x19, 0x7f, 0x76, 0xd3, 0x0b, 0x3f,
0xf4, 0xb0, 0x19, 0xbe, 0x3c, 0x26, 0xd1, 0xd6, 0x98, 0xa1, 0x1d, 0xf4, 0x0b, 0x67, 0xc6, 0xc5
};
const BYTE rgbEcDsaKnownAnswerTestK[32] = {
0x0a, 0xdc, 0xe3, 0x27, 0xd4, 0x62, 0x95, 0x3b, 0x3a, 0x4e, 0xfd, 0xa5, 0x07, 0x32, 0x6f, 0x3b,
0xda, 0xaa, 0x52, 0x4c, 0xad, 0x2d, 0xf6, 0x23, 0x8a, 0x93, 0x87, 0xdd, 0xd0, 0x25, 0x91, 0x00
};
const BYTE rgbEcDsaKnownAnswerTestSignature[64] = {
0x95, 0xc5, 0xd8, 0xce, 0xe6, 0xcf, 0x79, 0xd3, 0x13, 0x03, 0xf3, 0x96, 0x86, 0x0c, 0x4b, 0x0c,
0xe4, 0xdd, 0x61, 0x3d, 0x78, 0x24, 0x7a, 0x05, 0x56, 0x7e, 0x02, 0xaf, 0xdd, 0x57, 0x40, 0xd4,
0x7b, 0xeb, 0xae, 0xf3, 0x8a, 0x12, 0x16, 0xf6, 0x2b, 0x15, 0x6e, 0x98, 0x74, 0x32, 0xbd, 0x6b,
0x07, 0x09, 0xe2, 0x55, 0xeb, 0xfb, 0x0c, 0x18, 0xaf, 0xc3, 0xc2, 0x39, 0x78, 0x4e, 0x59, 0x40
}; };
VOID VOID
@ -708,7 +779,7 @@ SymCryptEcDhSecretAgreementSelftest(void)
VOID VOID
SYMCRYPT_CALL SYMCRYPT_CALL
SymCryptDsaSignVerifyTest( PCSYMCRYPT_DLKEY pkDlkey ) SymCryptDsaPct( PCSYMCRYPT_DLKEY pkDlkey )
{ {
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
@ -751,6 +822,8 @@ SymCryptDsaSelftest(void)
PSYMCRYPT_DLGROUP pDlgroup = NULL; PSYMCRYPT_DLGROUP pDlgroup = NULL;
PSYMCRYPT_DLKEY pkDlkey = NULL; PSYMCRYPT_DLKEY pkDlkey = NULL;
BYTE rgbSignature[64];
pDlgroup = SymCryptDlgroupAllocate( pDlgroup = SymCryptDlgroupAllocate(
sizeof(dsaDlgroup.primeP) * 8, sizeof(dsaDlgroup.primeP) * 8,
sizeof(dsaDlgroup.primeQ) * 8 ); sizeof(dsaDlgroup.primeQ) * 8 );
@ -785,7 +858,23 @@ SymCryptDsaSelftest(void)
pkDlkey ); pkDlkey );
SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR ); SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR );
SymCryptDsaSignVerifyTest( pkDlkey ); // DSA is no longer an approved signing algorithm, so we don't need to perform a signature in
// the CAST. We can just verify the precalculated signature. But for the unit test
// infrastructure to exercise these self-tests, we also need to to inject errors and ensure
// that the verification fails when the signature is corrupted.
C_ASSERT( sizeof(rgbDsaKnownAnswerTestSignature) == sizeof(rgbSignature) );
memcpy( rgbSignature, rgbDsaKnownAnswerTestSignature, sizeof(rgbDsaKnownAnswerTestSignature) );
SymCryptInjectError( rgbSignature, sizeof(rgbSignature) );
scError = SymCryptDsaVerify(
pkDlkey,
rgbSha256Hash,
sizeof(rgbSha256Hash),
rgbSignature,
sizeof(rgbSignature),
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0 );
SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR );
SymCryptDlkeyFree( pkDlkey ); SymCryptDlkeyFree( pkDlkey );
SymCryptDlgroupFree( pDlgroup ); SymCryptDlgroupFree( pDlgroup );
@ -793,7 +882,7 @@ SymCryptDsaSelftest(void)
VOID VOID
SYMCRYPT_CALL SYMCRYPT_CALL
SymCryptEcDsaSignVerifyTest( PCSYMCRYPT_ECKEY pkEckey ) SymCryptEcDsaPct( PCSYMCRYPT_ECKEY pkEckey )
{ {
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
@ -837,6 +926,9 @@ SymCryptEcDsaSelftest(void)
PSYMCRYPT_ECURVE pCurve = NULL; PSYMCRYPT_ECURVE pCurve = NULL;
PSYMCRYPT_ECKEY pkEckey = NULL; PSYMCRYPT_ECKEY pkEckey = NULL;
PSYMCRYPT_INT piK = NULL;
BYTE rgbSignature[64];
pCurve = SymCryptEcurveAllocate( SymCryptEcurveParamsNistP256, 0 ); pCurve = SymCryptEcurveAllocate( SymCryptEcurveParamsNistP256, 0 );
SYMCRYPT_FIPS_ASSERT( pCurve != NULL ); SYMCRYPT_FIPS_ASSERT( pCurve != NULL );
@ -844,6 +936,17 @@ SymCryptEcDsaSelftest(void)
pkEckey = SymCryptEckeyAllocate( pCurve ); pkEckey = SymCryptEckeyAllocate( pCurve );
SYMCRYPT_FIPS_ASSERT( pkEckey != NULL ); SYMCRYPT_FIPS_ASSERT( pkEckey != NULL );
piK = SymCryptIntAllocate(
SYMCRYPT_FDEF_DIGITS_FROM_BITS( sizeof(rgbEcDsaKnownAnswerTestK) * 8 ) );
SYMCRYPT_FIPS_ASSERT( piK != NULL );
scError = SymCryptIntSetValue(
rgbEcDsaKnownAnswerTestK,
sizeof(rgbEcDsaKnownAnswerTestK),
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
piK );
SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR );
scError = SymCryptEckeySetValue( scError = SymCryptEckeySetValue(
eckey1.d, eckey1.d,
sizeof(eckey1.d), sizeof(eckey1.d),
@ -855,15 +958,40 @@ SymCryptEcDsaSelftest(void)
pkEckey); pkEckey);
SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR ); SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR );
SymCryptEcDsaSignVerifyTest( pkEckey ); scError = SymCryptEcDsaSignEx(
pkEckey,
rgbSha256Hash,
sizeof(rgbSha256Hash),
piK,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0,
rgbSignature,
sizeof(rgbSignature) );
SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR );
SYMCRYPT_FIPS_ASSERT(
memcmp( rgbSignature, rgbEcDsaKnownAnswerTestSignature, sizeof(rgbSignature) ) == 0 );
SymCryptInjectError( rgbSignature, sizeof(rgbSignature) );
scError = SymCryptEcDsaVerify(
pkEckey,
rgbSha256Hash,
sizeof(rgbSha256Hash),
rgbSignature,
sizeof(rgbSignature),
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
0 );
SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR );
SymCryptIntFree( piK );
SymCryptEckeyFree( pkEckey ); SymCryptEckeyFree( pkEckey );
SymCryptEcurveFree( pCurve ); SymCryptEcurveFree( pCurve );
} }
VOID VOID
SYMCRYPT_CALL SYMCRYPT_CALL
SymCryptRsaSignVerifyTest( PCSYMCRYPT_RSAKEY pkRsakey ) SymCryptRsaSignVerifyPct( PCSYMCRYPT_RSAKEY pkRsakey )
{ {
SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR;
@ -911,6 +1039,10 @@ SymCryptRsaSelftest(void)
PSYMCRYPT_RSAKEY pkRsakey = NULL; PSYMCRYPT_RSAKEY pkRsakey = NULL;
SYMCRYPT_RSA_PARAMS rsaParams = { 0 }; SYMCRYPT_RSA_PARAMS rsaParams = { 0 };
SIZE_T cbSignature = sizeof(rgbRsaPkcs1Sig);
PBYTE pbSignature = SymCryptCallbackAlloc(cbSignature);
SYMCRYPT_FIPS_ASSERT(pbSignature != NULL);
rsaParams.version = 1; rsaParams.version = 1;
rsaParams.nBitsOfModulus = sizeof(rsakey.modulus) * 8; rsaParams.nBitsOfModulus = sizeof(rsakey.modulus) * 8;
rsaParams.nPrimes = 2; rsaParams.nPrimes = 2;
@ -919,8 +1051,8 @@ SymCryptRsaSelftest(void)
PCBYTE pbPrimes[] = { rsakey.prime1, rsakey.prime2 }; PCBYTE pbPrimes[] = { rsakey.prime1, rsakey.prime2 };
SIZE_T cbPrimes[] = { sizeof(rsakey.prime1), sizeof(rsakey.prime2) }; SIZE_T cbPrimes[] = { sizeof(rsakey.prime1), sizeof(rsakey.prime2) };
pkRsakey = SymCryptRsakeyAllocate( &rsaParams, 0 ); pkRsakey = SymCryptRsakeyAllocate(&rsaParams, 0);
SYMCRYPT_FIPS_ASSERT( pkRsakey != NULL ); SYMCRYPT_FIPS_ASSERT(pkRsakey != NULL);
scError = SymCryptRsakeySetValue( scError = SymCryptRsakeySetValue(
rsakey.modulus, rsakey.modulus,
@ -932,12 +1064,42 @@ SymCryptRsaSelftest(void)
sizeof(cbPrimes) / sizeof(cbPrimes[0]), sizeof(cbPrimes) / sizeof(cbPrimes[0]),
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
SYMCRYPT_FLAG_RSAKEY_SIGN | SYMCRYPT_FLAG_KEY_NO_FIPS, SYMCRYPT_FLAG_RSAKEY_SIGN | SYMCRYPT_FLAG_KEY_NO_FIPS,
pkRsakey ); pkRsakey);
SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR ); SYMCRYPT_FIPS_ASSERT(scError == SYMCRYPT_NO_ERROR);
SymCryptRsaSignVerifyTest( pkRsakey ); scError = SymCryptRsaPkcs1Sign(
pkRsakey,
rgbSha256Hash,
sizeof(rgbSha256Hash),
SymCryptSha256OidList,
SYMCRYPT_SHA256_OID_COUNT,
0,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
pbSignature,
cbSignature,
&cbSignature);
SYMCRYPT_FIPS_ASSERT(scError == SYMCRYPT_NO_ERROR);
SymCryptRsakeyFree( pkRsakey ); SYMCRYPT_FIPS_ASSERT(memcmp(pbSignature, rgbRsaPkcs1Sig, sizeof(rgbRsaPkcs1Sig)) == 0);
SymCryptInjectError(pbSignature, cbSignature);
scError = SymCryptRsaPkcs1Verify(
pkRsakey,
rgbSha256Hash,
sizeof(rgbSha256Hash),
pbSignature,
cbSignature,
SYMCRYPT_NUMBER_FORMAT_MSB_FIRST,
SymCryptSha256OidList,
SYMCRYPT_SHA256_OID_COUNT,
0);
SYMCRYPT_FIPS_ASSERT(scError == SYMCRYPT_NO_ERROR);
SymCryptRsakeyFree(pkRsakey);
SymCryptWipe(pbSignature, cbSignature);
SymCryptCallbackFree(pbSignature);
} }
VOID VOID

Просмотреть файл

@ -532,7 +532,7 @@ SymCryptRsakeyGenerate(
goto cleanup; goto cleanup;
} }
// SymCryptRsaSignVerifyTest self-test requires generated key to be at least 496 bits to avoid fatal // SymCryptRsaSignVerifyPct requires the generated key to be at least 496 bits to avoid fatal
// Require caller to specify NO_FIPS for up to 1024 bits as running FIPS tests on too-small keys // Require caller to specify NO_FIPS for up to 1024 bits as running FIPS tests on too-small keys
// does not make it FIPS certifiable and gives the wrong impression to callers // does not make it FIPS certifiable and gives the wrong impression to callers
if ( ( (flags & SYMCRYPT_FLAG_KEY_NO_FIPS) == 0 ) && if ( ( (flags & SYMCRYPT_FLAG_KEY_NO_FIPS) == 0 ) &&
@ -737,11 +737,10 @@ SymCryptRsakeyGenerate(
// Unconditionally set the sign flag to enable SignVerify PCT on encrypt-only keypair // Unconditionally set the sign flag to enable SignVerify PCT on encrypt-only keypair
pkRsakey->fAlgorithmInfo |= SYMCRYPT_FLAG_RSAKEY_SIGN; pkRsakey->fAlgorithmInfo |= SYMCRYPT_FLAG_RSAKEY_SIGN;
SYMCRYPT_RUN_KEYGEN_PCT( SYMCRYPT_RUN_KEY_PCT(
SymCryptRsaSignVerifyTest, SymCryptRsaSignVerifyPct,
pkRsakey, pkRsakey,
0, /* Do not set any algorithm selftest as run with this PCT */ SYMCRYPT_PCT_RSA_SIGN );
SYMCRYPT_SELFTEST_KEY_RSA_SIGN );
// Unset the sign flag before returning encrypt-only keypair // Unset the sign flag before returning encrypt-only keypair
if ( ( flags & SYMCRYPT_FLAG_RSAKEY_SIGN ) == 0 ) if ( ( flags & SYMCRYPT_FLAG_RSAKEY_SIGN ) == 0 )
@ -983,10 +982,18 @@ SymCryptRsakeySetValue(
SymCryptRsaSelftest, SymCryptRsaSelftest,
SYMCRYPT_SELFTEST_ALGORITHM_RSA); SYMCRYPT_SELFTEST_ALGORITHM_RSA);
if( pkRsakey->hasPrivateKey ) // Unconditionally set the sign flag to enable SignVerify PCT on encrypt-only keypair
pkRsakey->fAlgorithmInfo |= SYMCRYPT_FLAG_RSAKEY_SIGN;
SYMCRYPT_RUN_KEY_PCT(
SymCryptRsaSignVerifyPct,
pkRsakey,
SYMCRYPT_PCT_RSA_SIGN );
// Unset the sign flag before returning encrypt-only keypair
if ( ( flags & SYMCRYPT_FLAG_RSAKEY_SIGN ) == 0 )
{ {
// We do not need to run an RSA PCT on import, indicate that the test has been run pkRsakey->fAlgorithmInfo ^= SYMCRYPT_FLAG_RSAKEY_SIGN;
pkRsakey->fAlgorithmInfo |= SYMCRYPT_SELFTEST_KEY_RSA_SIGN;
} }
} }

Просмотреть файл

@ -3658,32 +3658,28 @@ SymCryptFdefMontgomeryReduceMulx1024(
// | | The current strategy will be to always perform the stronger tests. // | | The current strategy will be to always perform the stronger tests.
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// Macro for executing a module selftest and setting the corresponding algorithm selftest flag // Macro for executing a Cryptographic Algorithm Self-Test (CAST) and setting the corresponding
// flag. These selftests must be run once per algorithm before the algorithm is used. For algorithms
// like hashing and symmetric encryption which have a low performance cost, we run the CASTs when
// the module is loaded. For asymmetric algorithms, we defer the CASTs until the first use of the
// algorithm; hence we need flags to keep track of which CASTs have been run.
#define SYMCRYPT_RUN_SELFTEST_ONCE(AlgorithmSelftestFunction, AlgorithmSelftestFlag) \ #define SYMCRYPT_RUN_SELFTEST_ONCE(AlgorithmSelftestFunction, AlgorithmSelftestFlag) \
if( ( g_SymCryptFipsSelftestsPerformed & AlgorithmSelftestFlag ) == 0 ) \ if( ( g_SymCryptFipsSelftestsPerformed & AlgorithmSelftestFlag ) == 0 ) \
{ \ { \
AlgorithmSelftestFunction( ); \ AlgorithmSelftestFunction( ); \
\
SYMCRYPT_ATOMIC_OR32_PRE_RELAXED( &g_SymCryptFipsSelftestsPerformed, AlgorithmSelftestFlag ); \ SYMCRYPT_ATOMIC_OR32_PRE_RELAXED( &g_SymCryptFipsSelftestsPerformed, AlgorithmSelftestFlag ); \
} }
// Macro for executing a key-generation PCT, setting the corresponding algorithm selftest flag, and // Macro for executing a pairwise consistency test on a key and setting the per-key selftest flag.
// setting the per-key selftest flag. // Typically PCTs must be run for each key before the key is first used or exported, but the
// Note that key generation PCTs must be run on every key generated, so the KeySelftestFunction // specific requirements vary between algorithms.
// function is run regardless of whether the algorithm selftest flag is already set. Normally the //
// per-key PCT satisfies the algorithm test requirement, so setting the AlgorithmSelftestFlag here // Note that a PCT is not considered a CAST and thus does not satisfy the aforementioned requirement
// prevents subsequent algorithm selftests from being run on key import. If the PCT does not satisfy // for algorithm selftests.
// an algorithm test requirment, the caller can specify 0, and no flag will be set. #define SYMCRYPT_RUN_KEY_PCT(KeySelftestFunction, Key, KeySelftestFlag) \
#define SYMCRYPT_RUN_KEYGEN_PCT(KeySelftestFunction, Key, AlgorithmSelftestFlag, KeySelftestFlag) \
if( ( Key->fAlgorithmInfo & (KeySelftestFlag | SYMCRYPT_FLAG_KEY_NO_FIPS) ) == 0 ) \ if( ( Key->fAlgorithmInfo & (KeySelftestFlag | SYMCRYPT_FLAG_KEY_NO_FIPS) ) == 0 ) \
{ \ { \
KeySelftestFunction( Key ); \ KeySelftestFunction( Key ); \
\
if( ( g_SymCryptFipsSelftestsPerformed & AlgorithmSelftestFlag ) != AlgorithmSelftestFlag ) \
{ \
SYMCRYPT_ATOMIC_OR32_PRE_RELAXED(&g_SymCryptFipsSelftestsPerformed, AlgorithmSelftestFlag); \
} \
\
SYMCRYPT_ATOMIC_OR32_PRE_RELAXED(&Key->fAlgorithmInfo, KeySelftestFlag); \ SYMCRYPT_ATOMIC_OR32_PRE_RELAXED(&Key->fAlgorithmInfo, KeySelftestFlag); \
} }
@ -3695,9 +3691,9 @@ if( ( Key->fAlgorithmInfo & (KeySelftestFlag | SYMCRYPT_FLAG_KEY_NO_FIPS) ) == 0
#define CHECK_ALGORITHM_INFO_FLAGS_DISTINCT( flag0, flag1, flag2, flag3, flag4 ) \ #define CHECK_ALGORITHM_INFO_FLAGS_DISTINCT( flag0, flag1, flag2, flag3, flag4 ) \
C_ASSERT( (flag0 < flag1) && (flag1 < flag2) && (flag2 < flag3) && (flag3 < flag4) ); C_ASSERT( (flag0 < flag1) && (flag1 < flag2) && (flag2 < flag3) && (flag3 < flag4) );
CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_SELFTEST_KEY_DSA); CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_PCT_DSA);
CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_SELFTEST_KEY_ECDSA); CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_PCT_ECDSA);
CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_SELFTEST_KEY_RSA_SIGN); CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_PCT_RSA_SIGN);
CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_FLAG_KEY_NO_FIPS); CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_FLAG_KEY_NO_FIPS);
CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION); CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION);
@ -3711,29 +3707,29 @@ CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_FLAG_ECKEY_ECDH);
CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_FLAG_RSAKEY_SIGN); CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_FLAG_RSAKEY_SIGN);
CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_FLAG_RSAKEY_ENCRYPT); CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_FLAG_RSAKEY_ENCRYPT);
CHECK_ALGORITHM_INFO_FLAGS_DISTINCT(SYMCRYPT_SELFTEST_KEY_DSA, SYMCRYPT_FLAG_KEY_NO_FIPS, SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION, SYMCRYPT_FLAG_DLKEY_DSA, SYMCRYPT_FLAG_DLKEY_DH); CHECK_ALGORITHM_INFO_FLAGS_DISTINCT(SYMCRYPT_PCT_DSA, SYMCRYPT_FLAG_KEY_NO_FIPS, SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION, SYMCRYPT_FLAG_DLKEY_DSA, SYMCRYPT_FLAG_DLKEY_DH);
CHECK_ALGORITHM_INFO_FLAGS_DISTINCT(SYMCRYPT_SELFTEST_KEY_ECDSA, SYMCRYPT_FLAG_KEY_NO_FIPS, SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION, SYMCRYPT_FLAG_ECKEY_ECDSA, SYMCRYPT_FLAG_ECKEY_ECDH); CHECK_ALGORITHM_INFO_FLAGS_DISTINCT(SYMCRYPT_PCT_ECDSA, SYMCRYPT_FLAG_KEY_NO_FIPS, SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION, SYMCRYPT_FLAG_ECKEY_ECDSA, SYMCRYPT_FLAG_ECKEY_ECDH);
CHECK_ALGORITHM_INFO_FLAGS_DISTINCT(SYMCRYPT_SELFTEST_KEY_RSA_SIGN, SYMCRYPT_FLAG_KEY_NO_FIPS, SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION, SYMCRYPT_FLAG_RSAKEY_SIGN, SYMCRYPT_FLAG_RSAKEY_ENCRYPT); CHECK_ALGORITHM_INFO_FLAGS_DISTINCT(SYMCRYPT_PCT_RSA_SIGN, SYMCRYPT_FLAG_KEY_NO_FIPS, SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION, SYMCRYPT_FLAG_RSAKEY_SIGN, SYMCRYPT_FLAG_RSAKEY_ENCRYPT);
VOID VOID
SYMCRYPT_CALL SYMCRYPT_CALL
SymCryptRsaSignVerifyTest( PCSYMCRYPT_RSAKEY pkRsakey ); SymCryptRsaSignVerifyPct( PCSYMCRYPT_RSAKEY pkRsakey );
// //
// FIPS PCT for RSA sign/verify. If the self-test fails, SymCryptFatal will be called to fastfail. // FIPS pairwise consistency test for RSA sign/verify. Fastfails on error.
// //
VOID VOID
SYMCRYPT_CALL SYMCRYPT_CALL
SymCryptDsaSignVerifyTest( PCSYMCRYPT_DLKEY pkDlkey ); SymCryptDsaPct( PCSYMCRYPT_DLKEY pkDlkey );
// //
// FIPS PCT for DSA sign/verify. If the self-test fails, SymCryptFatal will be called to fastfail. // FIPS pairwise consistency test for DSA sign/verify. Fastfails on error.
// //
VOID VOID
SYMCRYPT_CALL SYMCRYPT_CALL
SymCryptEcDsaSignVerifyTest( PCSYMCRYPT_ECKEY pkEckey ); SymCryptEcDsaPct( PCSYMCRYPT_ECKEY pkEckey );
// //
// FIPS PCT for ECDSA sign/verify. If the self-test fails, SymCryptFatal will be called to fastfail. // FIPS pairwise consistency test for ECDSA sign/verify. Fastfails on error.
// //
typedef struct _SYMCRYPT_DLGROUP_DH_SAFEPRIME_PARAMS { typedef struct _SYMCRYPT_DLGROUP_DH_SAFEPRIME_PARAMS {

Просмотреть файл

@ -65,8 +65,14 @@ VOID testSelftestOne( const SELFTEST_INFO * pSelfTestInfo, PrintTable* perfTable
} }
} }
// Get the average number of clock cycles each selftest takes per iteration, so that we can catch // Get the average number of clock cycles each selftest takes per iteration, so that we can
// regressions or unacceptably slow tests when we add new ones. // catch performance regressions or unacceptably slow tests when we add new ones. Note that for
// measuring algorithm performance (i.e. not selftests), the unit tests use linear regression
// to determine the average number of cycles per byte, and fixed overhead, across many runs.
// We do not yet perform linear regression on the selftest performance results, so they will be
// less accurate and may show unexpected values for platforms where we don't affinitize the
// unit test thread to a single core (e.g. Linux), or on architectures where clock cycle count
// varies based on CPU frequency (e.g. AMD64).
ULONGLONG clockCycleAverage = clockSum / (nTries - nInject); ULONGLONG clockCycleAverage = clockSum / (nTries - nInject);
perfTable->addItem( pSelfTestInfo->name, "Cycles", clockCycleAverage ); perfTable->addItem( pSelfTestInfo->name, "Cycles", clockCycleAverage );

Просмотреть файл

@ -667,7 +667,7 @@ EXPORTS
SymCryptEcpointSetRandom SymCryptEcpointSetRandom
SymCryptEcpointScalarMul SymCryptEcpointScalarMul
SymCryptEcpointMultiScalarMul SymCryptEcpointMultiScalarMul
SymCryptEcDsaSignEx SymCryptEcDsaSignEx ; deterministic ECDSA signing, only to be used by unit tests
SymCrypt802_11SaeGetGroupSizes SymCrypt802_11SaeGetGroupSizes
SymCrypt802_11SaeCustomInit SymCrypt802_11SaeCustomInit
SymCrypt802_11SaeCustomCreatePT SymCrypt802_11SaeCustomCreatePT