From 3b4cad7a6a9f9b392762e56a20a2e9464d0a1785 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mitch=20Lindgren=20=F0=9F=A6=8E?= Date: Fri, 30 Aug 2024 05:26:38 +0000 Subject: [PATCH] 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 --- doc/breaking_changes.md | 7 +- inc/symcrypt.h | 2 +- inc/symcrypt_internal.h | 13 +- lib/dlkey.c | 18 +- lib/ec_dsa.c | 7 +- lib/eckey.c | 14 +- lib/fips_selftest.c | 316 +++++++++++++++++++++------- lib/rsakey.c | 23 +- lib/sc_lib.h | 52 +++-- unittest/lib/testSelftest.cpp | 10 +- unittest/module_windows/exports.def | 2 +- 11 files changed, 324 insertions(+), 140 deletions(-) diff --git a/doc/breaking_changes.md b/doc/breaking_changes.md index 6cb383b..5c78b28 100644 --- a/doc/breaking_changes.md +++ b/doc/breaking_changes.md @@ -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. ### 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. \ No newline at end of file +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. \ No newline at end of file diff --git a/inc/symcrypt.h b/inc/symcrypt.h index 3ac32ef..a52756b 100644 --- a/inc/symcrypt.h +++ b/inc/symcrypt.h @@ -7367,7 +7367,7 @@ SymCryptDlkeyExtendKeyUsage( // 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 // 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: // SYMCRYPT_FLAG_DLKEY_DSA diff --git a/inc/symcrypt_internal.h b/inc/symcrypt_internal.h index ee9dbde..36a49cc 100644 --- a/inc/symcrypt_internal.h +++ b/inc/symcrypt_internal.h @@ -2417,7 +2417,7 @@ typedef SYMCRYPT_ASYM_ALIGN_STRUCT _SYMCRYPT_RSAKEY { UINT32 fAlgorithmInfo; // Tracks which algorithms the key can be used in // Also tracks which per-key selftests have been performed on this key // 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 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 // Also tracks which per-key selftests have been performed on this key // 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 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 // Also tracks which per-key selftests have been performed on this key // 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 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 // 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). +// +// 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 // DSA Pairwise Consistency Test to be run generated keys #define SYMCRYPT_SELFTEST_KEY_DSA (0x1) +#define SYMCRYPT_PCT_DSA SYMCRYPT_SELFTEST_KEY_DSA // Eckey selftest flags // ECDSA Pairwise Consistency Test to be run generated keys #define SYMCRYPT_SELFTEST_KEY_ECDSA (0x1) +#define SYMCRYPT_PCT_ECDSA SYMCRYPT_SELFTEST_KEY_ECDSA // Rsakey selftest flags // RSA Pairwise Consistency Test to be run generated keys #define SYMCRYPT_SELFTEST_KEY_RSA_SIGN (0x1) +#define SYMCRYPT_PCT_RSA_SIGN SYMCRYPT_SELFTEST_KEY_RSA_SIGN UINT32 SYMCRYPT_CALL diff --git a/lib/dlkey.c b/lib/dlkey.c index c120ead..c358556 100644 --- a/lib/dlkey.c +++ b/lib/dlkey.c @@ -480,12 +480,16 @@ SymCryptDlkeyGenerate( { 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 - SYMCRYPT_RUN_KEYGEN_PCT( - SymCryptDsaSignVerifyTest, + SYMCRYPT_RUN_KEY_PCT( + SymCryptDsaPct, pkDlkey, - SYMCRYPT_SELFTEST_ALGORITHM_DSA, - SYMCRYPT_SELFTEST_KEY_DSA ); + SYMCRYPT_PCT_DSA ); } if( ( flags & SYMCRYPT_FLAG_DLKEY_DH ) != 0 ) @@ -796,8 +800,10 @@ SymCryptDlkeySetValue( if( pkDlkey->fHasPrivateKey ) { - // We do not need to run a DSA PCT on import, indicate that the test has been run - pkDlkey->fAlgorithmInfo |= SYMCRYPT_SELFTEST_KEY_DSA; + SYMCRYPT_RUN_KEY_PCT( + SymCryptDsaPct, + pkDlkey, + SYMCRYPT_PCT_DSA ); } } diff --git a/lib/ec_dsa.c b/lib/ec_dsa.c index 744d9cd..79138a2 100644 --- a/lib/ec_dsa.c +++ b/lib/ec_dsa.c @@ -418,11 +418,10 @@ SymCryptEcDsaSign( } // If the key was generated and a PCT has not yet been performed - perform PCT before first use - SYMCRYPT_RUN_KEYGEN_PCT( - SymCryptEcDsaSignVerifyTest, + SYMCRYPT_RUN_KEY_PCT( + SymCryptEcDsaPct, pKey, - SYMCRYPT_SELFTEST_ALGORITHM_ECDSA, - SYMCRYPT_SELFTEST_KEY_ECDSA ); + SYMCRYPT_PCT_ECDSA ); return SymCryptEcDsaSignEx( pKey, pbHashValue, cbHashValue, NULL, format, flags, pbSignature, cbSignature ); } diff --git a/lib/eckey.c b/lib/eckey.c index b0080f7..5629ac5 100644 --- a/lib/eckey.c +++ b/lib/eckey.c @@ -547,11 +547,8 @@ SymCryptEckeySetValue( SymCryptEcDsaSelftest, SYMCRYPT_SELFTEST_ALGORITHM_ECDSA ); - if( pEckey->hasPrivateKey ) - { - // We do not need to run an ECDSA PCT on import, indicate that the test has been run - pEckey->fAlgorithmInfo |= SYMCRYPT_SELFTEST_KEY_ECDSA; - } + // ECDSA PCT is deferred until the key is used or exported - see SymCryptEcDsaSign and + // SymCryptEckeyGetValue } if ( ( flags & SYMCRYPT_FLAG_ECKEY_ECDH ) != 0 ) @@ -658,11 +655,10 @@ SymCryptEckeyGetValue( if ( ((pEckey->fAlgorithmInfo & SYMCRYPT_FLAG_ECKEY_ECDSA) != 0) && ((pEckey->fAlgorithmInfo & SYMCRYPT_FLAG_KEY_NO_FIPS) == 0) ) { - SYMCRYPT_RUN_KEYGEN_PCT( - SymCryptEcDsaSignVerifyTest, + SYMCRYPT_RUN_KEY_PCT( + SymCryptEcDsaPct, pEckey, - SYMCRYPT_SELFTEST_ALGORITHM_ECDSA, - SYMCRYPT_SELFTEST_KEY_ECDSA ); + SYMCRYPT_PCT_ECDSA ); } // Copy the key into the temporary integer diff --git a/lib/fips_selftest.c b/lib/fips_selftest.c index dd3d09e..bd79f60 100644 --- a/lib/fips_selftest.c +++ b/lib/fips_selftest.c @@ -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 // Hashed from: { 0x61, 0x62, 0x63 } const BYTE rgbSha256Hash[] = { - 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, - 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, - 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, - 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad + 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad }; @@ -509,72 +529,123 @@ const BYTE rgbXmssSha2_10_192Signature[] = 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, + 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, + 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, + 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, +}; + +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 @@ -708,7 +779,7 @@ SymCryptEcDhSecretAgreementSelftest(void) VOID SYMCRYPT_CALL -SymCryptDsaSignVerifyTest( PCSYMCRYPT_DLKEY pkDlkey ) +SymCryptDsaPct( PCSYMCRYPT_DLKEY pkDlkey ) { SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; @@ -751,6 +822,8 @@ SymCryptDsaSelftest(void) PSYMCRYPT_DLGROUP pDlgroup = NULL; PSYMCRYPT_DLKEY pkDlkey = NULL; + BYTE rgbSignature[64]; + pDlgroup = SymCryptDlgroupAllocate( sizeof(dsaDlgroup.primeP) * 8, sizeof(dsaDlgroup.primeQ) * 8 ); @@ -785,7 +858,23 @@ SymCryptDsaSelftest(void) pkDlkey ); 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 ); SymCryptDlgroupFree( pDlgroup ); @@ -793,7 +882,7 @@ SymCryptDsaSelftest(void) VOID SYMCRYPT_CALL -SymCryptEcDsaSignVerifyTest( PCSYMCRYPT_ECKEY pkEckey ) +SymCryptEcDsaPct( PCSYMCRYPT_ECKEY pkEckey ) { SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; @@ -837,6 +926,9 @@ SymCryptEcDsaSelftest(void) PSYMCRYPT_ECURVE pCurve = NULL; PSYMCRYPT_ECKEY pkEckey = NULL; + PSYMCRYPT_INT piK = NULL; + + BYTE rgbSignature[64]; pCurve = SymCryptEcurveAllocate( SymCryptEcurveParamsNistP256, 0 ); SYMCRYPT_FIPS_ASSERT( pCurve != NULL ); @@ -844,6 +936,17 @@ SymCryptEcDsaSelftest(void) pkEckey = SymCryptEckeyAllocate( pCurve ); 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( eckey1.d, sizeof(eckey1.d), @@ -855,15 +958,40 @@ SymCryptEcDsaSelftest(void) pkEckey); 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 ); SymCryptEcurveFree( pCurve ); } VOID SYMCRYPT_CALL -SymCryptRsaSignVerifyTest( PCSYMCRYPT_RSAKEY pkRsakey ) +SymCryptRsaSignVerifyPct( PCSYMCRYPT_RSAKEY pkRsakey ) { SYMCRYPT_ERROR scError = SYMCRYPT_NO_ERROR; @@ -911,6 +1039,10 @@ SymCryptRsaSelftest(void) PSYMCRYPT_RSAKEY pkRsakey = NULL; SYMCRYPT_RSA_PARAMS rsaParams = { 0 }; + SIZE_T cbSignature = sizeof(rgbRsaPkcs1Sig); + PBYTE pbSignature = SymCryptCallbackAlloc(cbSignature); + SYMCRYPT_FIPS_ASSERT(pbSignature != NULL); + rsaParams.version = 1; rsaParams.nBitsOfModulus = sizeof(rsakey.modulus) * 8; rsaParams.nPrimes = 2; @@ -919,8 +1051,8 @@ SymCryptRsaSelftest(void) PCBYTE pbPrimes[] = { rsakey.prime1, rsakey.prime2 }; SIZE_T cbPrimes[] = { sizeof(rsakey.prime1), sizeof(rsakey.prime2) }; - pkRsakey = SymCryptRsakeyAllocate( &rsaParams, 0 ); - SYMCRYPT_FIPS_ASSERT( pkRsakey != NULL ); + pkRsakey = SymCryptRsakeyAllocate(&rsaParams, 0); + SYMCRYPT_FIPS_ASSERT(pkRsakey != NULL); scError = SymCryptRsakeySetValue( rsakey.modulus, @@ -932,12 +1064,42 @@ SymCryptRsaSelftest(void) sizeof(cbPrimes) / sizeof(cbPrimes[0]), SYMCRYPT_NUMBER_FORMAT_MSB_FIRST, SYMCRYPT_FLAG_RSAKEY_SIGN | SYMCRYPT_FLAG_KEY_NO_FIPS, - pkRsakey ); - SYMCRYPT_FIPS_ASSERT( scError == SYMCRYPT_NO_ERROR ); + pkRsakey); + 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 diff --git a/lib/rsakey.c b/lib/rsakey.c index 1ddee43..f3d45e2 100644 --- a/lib/rsakey.c +++ b/lib/rsakey.c @@ -532,7 +532,7 @@ SymCryptRsakeyGenerate( 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 // does not make it FIPS certifiable and gives the wrong impression to callers 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 pkRsakey->fAlgorithmInfo |= SYMCRYPT_FLAG_RSAKEY_SIGN; - SYMCRYPT_RUN_KEYGEN_PCT( - SymCryptRsaSignVerifyTest, + SYMCRYPT_RUN_KEY_PCT( + SymCryptRsaSignVerifyPct, pkRsakey, - 0, /* Do not set any algorithm selftest as run with this PCT */ - SYMCRYPT_SELFTEST_KEY_RSA_SIGN ); + SYMCRYPT_PCT_RSA_SIGN ); // Unset the sign flag before returning encrypt-only keypair if ( ( flags & SYMCRYPT_FLAG_RSAKEY_SIGN ) == 0 ) @@ -983,10 +982,18 @@ SymCryptRsakeySetValue( SymCryptRsaSelftest, 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_SELFTEST_KEY_RSA_SIGN; + pkRsakey->fAlgorithmInfo ^= SYMCRYPT_FLAG_RSAKEY_SIGN; } } diff --git a/lib/sc_lib.h b/lib/sc_lib.h index 1b48239..bbb8575 100644 --- a/lib/sc_lib.h +++ b/lib/sc_lib.h @@ -3658,32 +3658,28 @@ SymCryptFdefMontgomeryReduceMulx1024( // | | 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) \ if( ( g_SymCryptFipsSelftestsPerformed & AlgorithmSelftestFlag ) == 0 ) \ { \ AlgorithmSelftestFunction( ); \ -\ SYMCRYPT_ATOMIC_OR32_PRE_RELAXED( &g_SymCryptFipsSelftestsPerformed, AlgorithmSelftestFlag ); \ } -// Macro for executing a key-generation PCT, setting the corresponding algorithm selftest flag, and -// setting the per-key selftest flag. -// Note that key generation PCTs must be run on every key generated, so the KeySelftestFunction -// 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 -// prevents subsequent algorithm selftests from being run on key import. If the PCT does not satisfy -// an algorithm test requirment, the caller can specify 0, and no flag will be set. -#define SYMCRYPT_RUN_KEYGEN_PCT(KeySelftestFunction, Key, AlgorithmSelftestFlag, KeySelftestFlag) \ +// Macro for executing a pairwise consistency test on a key and setting the per-key selftest flag. +// Typically PCTs must be run for each key before the key is first used or exported, but the +// specific requirements vary between algorithms. +// +// Note that a PCT is not considered a CAST and thus does not satisfy the aforementioned requirement +// for algorithm selftests. +#define SYMCRYPT_RUN_KEY_PCT(KeySelftestFunction, Key, KeySelftestFlag) \ if( ( Key->fAlgorithmInfo & (KeySelftestFlag | SYMCRYPT_FLAG_KEY_NO_FIPS) ) == 0 ) \ { \ KeySelftestFunction( Key ); \ -\ - if( ( g_SymCryptFipsSelftestsPerformed & AlgorithmSelftestFlag ) != AlgorithmSelftestFlag ) \ - { \ - SYMCRYPT_ATOMIC_OR32_PRE_RELAXED(&g_SymCryptFipsSelftestsPerformed, AlgorithmSelftestFlag); \ - } \ -\ 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 ) \ 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_SELFTEST_KEY_ECDSA); -CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_SELFTEST_KEY_RSA_SIGN); +CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_PCT_DSA); +CHECK_ALGORITHM_INFO_FLAG_POW2(SYMCRYPT_PCT_ECDSA); +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_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_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_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_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_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_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_RSA_SIGN, SYMCRYPT_FLAG_KEY_NO_FIPS, SYMCRYPT_FLAG_KEY_MINIMAL_VALIDATION, SYMCRYPT_FLAG_RSAKEY_SIGN, SYMCRYPT_FLAG_RSAKEY_ENCRYPT); VOID 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 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 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 { diff --git a/unittest/lib/testSelftest.cpp b/unittest/lib/testSelftest.cpp index 1dd2298..2236853 100644 --- a/unittest/lib/testSelftest.cpp +++ b/unittest/lib/testSelftest.cpp @@ -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 - // regressions or unacceptably slow tests when we add new ones. + // Get the average number of clock cycles each selftest takes per iteration, so that we can + // 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); perfTable->addItem( pSelfTestInfo->name, "Cycles", clockCycleAverage ); diff --git a/unittest/module_windows/exports.def b/unittest/module_windows/exports.def index 7a9e300..469c8e2 100644 --- a/unittest/module_windows/exports.def +++ b/unittest/module_windows/exports.def @@ -667,7 +667,7 @@ EXPORTS SymCryptEcpointSetRandom SymCryptEcpointScalarMul SymCryptEcpointMultiScalarMul - SymCryptEcDsaSignEx + SymCryptEcDsaSignEx ; deterministic ECDSA signing, only to be used by unit tests SymCrypt802_11SaeGetGroupSizes SymCrypt802_11SaeCustomInit SymCrypt802_11SaeCustomCreatePT