2018-11-17 03:28:12 +03:00
|
|
|
//
|
2022-08-05 23:01:21 +03:00
|
|
|
// Pattern file for the SymCrypt hash implementations.
|
2018-11-17 03:28:12 +03:00
|
|
|
//
|
2019-04-12 01:52:13 +03:00
|
|
|
// Copyright (c) Microsoft Corporation. Licensed under the MIT license.
|
2018-11-17 03:28:12 +03:00
|
|
|
//
|
|
|
|
|
2022-08-05 23:01:21 +03:00
|
|
|
template<> VOID algImpKeyPerfFunction<ImpXxx,AlgXxx>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize );
|
2018-11-17 03:28:12 +03:00
|
|
|
template<> VOID algImpDataPerfFunction<ImpXxx,AlgXxx>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize );
|
|
|
|
template<> VOID algImpCleanPerfFunction<ImpXxx,AlgXxx>( PBYTE buf1, PBYTE buf2, PBYTE buf3 );
|
|
|
|
|
|
|
|
//
|
|
|
|
// Empty constructor.
|
|
|
|
//
|
|
|
|
template<>
|
|
|
|
HashImp< ImpXxx, AlgXxx >::HashImp()
|
|
|
|
{
|
|
|
|
|
|
|
|
m_perfDataFunction = &algImpDataPerfFunction <ImpXxx, AlgXxx>;
|
|
|
|
m_perfKeyFunction = &algImpKeyPerfFunction <ImpXxx, AlgXxx>;
|
|
|
|
m_perfCleanFunction= &algImpCleanPerfFunction<ImpXxx, AlgXxx>;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Check SymCrypt state import errors
|
|
|
|
//
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XXX_STATE hashState;
|
|
|
|
BYTE exportBlob[SCSHIM_XXX_STATE_EXPORT_SIZE];
|
2018-11-17 03:28:12 +03:00
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxInit( &hashState );
|
2018-11-17 03:28:12 +03:00
|
|
|
for( int i=0; i<200; i++ )
|
|
|
|
{
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxAppend( &hashState, (PCBYTE) &i, sizeof( i ) );
|
2018-11-17 03:28:12 +03:00
|
|
|
}
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxStateExport( &hashState, &exportBlob[0] );
|
2018-11-17 03:28:12 +03:00
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
for( int i=0; i<SCSHIM_XXX_STATE_EXPORT_SIZE; i++ )
|
2018-11-17 03:28:12 +03:00
|
|
|
{
|
|
|
|
exportBlob[i]++;
|
2024-05-10 09:48:11 +03:00
|
|
|
CHECK3( SCSHIM_XxxStateImport( &hashState, &exportBlob[0] ) == SYMCRYPT_INVALID_BLOB, "SymCrypt hash state import success on corrupt blob %d", i );
|
2018-11-17 03:28:12 +03:00
|
|
|
exportBlob[i]--;
|
|
|
|
}
|
2024-05-10 09:48:11 +03:00
|
|
|
CHECK( SCSHIM_XxxStateImport( &hashState, &exportBlob[0] ) == SYMCRYPT_NO_ERROR, "??" );
|
2018-11-17 03:28:12 +03:00
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
CHECK( ScShimSymCryptHashStateSize( SCSHIM_XxxAlgorithm ) == sizeof( SCSHIM_XXX_STATE ), "State size mismatch" );
|
2018-11-17 03:28:12 +03:00
|
|
|
|
|
|
|
state.isReset = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Empty destructor
|
|
|
|
//
|
|
|
|
template<>
|
|
|
|
HashImp<ImpXxx,AlgXxx>::~HashImp<ImpXxx, AlgXxx>()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
SIZE_T HashImp<ImpXxx,AlgXxx>::inputBlockLen()
|
|
|
|
{
|
2024-05-10 09:48:11 +03:00
|
|
|
CHECK( SCSHIM_XXX_INPUT_BLOCK_SIZE == ScShimSymCryptHashInputBlockSize(SCSHIM_XxxAlgorithm), "?" );
|
2018-11-17 03:28:12 +03:00
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
return SCSHIM_XXX_INPUT_BLOCK_SIZE;
|
2018-11-17 03:28:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
SIZE_T HashImp<ImpXxx,AlgXxx>::resultLen()
|
|
|
|
{
|
2024-05-10 09:48:11 +03:00
|
|
|
CHECK( SCSHIM_XXX_RESULT_SIZE == ScShimSymCryptHashResultSize(SCSHIM_XxxAlgorithm), "?" );
|
2018-11-17 03:28:12 +03:00
|
|
|
//
|
|
|
|
// The macro expands to <IMPNAME>_<ALGNAME>_RESULT_SIZE
|
|
|
|
//
|
2024-05-10 09:48:11 +03:00
|
|
|
return SCSHIM_XXX_RESULT_SIZE;
|
2018-11-17 03:28:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Compute a hash directly
|
|
|
|
//
|
|
|
|
template<>
|
|
|
|
VOID HashImp<ImpXxx,AlgXxx>::hash(
|
|
|
|
_In_reads_( cbData ) PCBYTE pbData,
|
|
|
|
SIZE_T cbData,
|
|
|
|
_Out_writes_( cbResult ) PBYTE pbResult,
|
|
|
|
SIZE_T cbResult )
|
|
|
|
{
|
2024-05-10 09:48:11 +03:00
|
|
|
BYTE splitResult[SCSHIM_XXX_RESULT_SIZE];
|
|
|
|
BYTE exportBlob[SCSHIM_XXX_STATE_EXPORT_SIZE];
|
2018-11-17 03:28:12 +03:00
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XXX_STATE state1;
|
|
|
|
SCSHIM_XXX_STATE state2;
|
2018-11-17 03:28:12 +03:00
|
|
|
SIZE_T halfSize = cbData >> 1;
|
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
CHECK( cbResult == SCSHIM_XXX_RESULT_SIZE, "Result len error in SymCrypt" STRING( ALG_Name ) );
|
|
|
|
SCSHIM_Xxx( pbData, cbData, pbResult );
|
2018-11-17 03:28:12 +03:00
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
ScShimSymCryptHash( SCSHIM_XxxAlgorithm, pbData, cbData, splitResult, cbResult);
|
|
|
|
CHECK(memcmp(splitResult, pbResult, SCSHIM_XXX_RESULT_SIZE) == 0, "Generic hash error in SymCrypt" STRING(ALG_Name));
|
2018-11-17 03:28:12 +03:00
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxInit( &state1 );
|
|
|
|
SCSHIM_XxxAppend( &state1, pbData, halfSize );
|
|
|
|
SCSHIM_XxxStateCopy( &state1, &state2 );
|
|
|
|
SCSHIM_XxxAppend( &state2, pbData+halfSize, cbData-halfSize );
|
|
|
|
SCSHIM_XxxResult( &state2, splitResult );
|
|
|
|
CHECK( memcmp( splitResult, pbResult, SCSHIM_XXX_RESULT_SIZE ) == 0, "State copy error in SymCrypt" STRING( ALG_Name ) );
|
2018-11-17 03:28:12 +03:00
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxInit( &state1 );
|
|
|
|
SCSHIM_XxxAppend( &state1, pbData, halfSize );
|
|
|
|
SCSHIM_XxxStateExport( &state1, &exportBlob[0] );
|
2018-11-17 03:28:12 +03:00
|
|
|
|
2022-08-05 23:01:21 +03:00
|
|
|
ScShimSymCryptWipe( &state2, sizeof( state2 ) );
|
2024-05-10 09:48:11 +03:00
|
|
|
CHECK( SCSHIM_XxxStateImport( &state2, &exportBlob[0] ) == SYMCRYPT_NO_ERROR , "SymCrypt hash state import error" );
|
|
|
|
SCSHIM_XxxAppend( &state2, pbData+halfSize, cbData-halfSize );
|
|
|
|
SCSHIM_XxxResult( &state2, splitResult );
|
|
|
|
CHECK( memcmp( splitResult, pbResult, SCSHIM_XXX_RESULT_SIZE ) == 0, "Import/Export error in SymCrypt" STRING( ALG_Name ) );
|
2022-08-05 23:01:21 +03:00
|
|
|
|
2018-11-17 03:28:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
|
|
// The init/append/result functions map directly to SymCrypt calls
|
|
|
|
// We use macros to generate the correct function names
|
|
|
|
//
|
|
|
|
|
|
|
|
template<>
|
|
|
|
VOID HashImp<ImpXxx,AlgXxx>::init()
|
|
|
|
{
|
|
|
|
if( !state.isReset || (g_rng.byte() & 1) == 0 )
|
|
|
|
{
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxInit( &state.sc );
|
|
|
|
ScShimSymCryptHashInit( SCSHIM_XxxAlgorithm, &state.scHash );
|
2018-11-17 03:28:12 +03:00
|
|
|
}
|
|
|
|
state.isReset = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
VOID HashImp<ImpXxx,AlgXxx>::append( _In_reads_( cbData ) PCBYTE pbData, SIZE_T cbData )
|
|
|
|
{
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxAppend( &state.sc, pbData, cbData );
|
|
|
|
ScShimSymCryptHashAppend( SCSHIM_XxxAlgorithm, &state.scHash, pbData, cbData );
|
2018-11-17 03:28:12 +03:00
|
|
|
state.isReset = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
VOID HashImp<ImpXxx,AlgXxx>::result( _Out_writes_( cbResult ) PBYTE pbResult, SIZE_T cbResult )
|
|
|
|
{
|
|
|
|
BYTE buf[SYMCRYPT_HASH_MAX_RESULT_SIZE];
|
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
CHECK( cbResult == SCSHIM_XXX_RESULT_SIZE, "Result len error in SymCrypt " STRING( ALG_Name ) );
|
|
|
|
SCSHIM_XxxResult( &state.sc, pbResult );
|
|
|
|
ScShimSymCryptHashResult( SCSHIM_XxxAlgorithm, &state.scHash, buf, sizeof( buf ) );
|
2018-11-17 03:28:12 +03:00
|
|
|
CHECK( memcmp( pbResult, buf, cbResult ) == 0, "Inconsistent result" );
|
|
|
|
state.isReset = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
NTSTATUS HashImp<ImpXxx,AlgXxx>::exportSymCryptFormat(
|
|
|
|
_Out_writes_bytes_to_( cbResultBufferSize, *pcbResult ) PBYTE pbResult,
|
|
|
|
_In_ SIZE_T cbResultBufferSize,
|
|
|
|
_Out_ SIZE_T *pcbResult )
|
|
|
|
{
|
2024-05-10 09:48:11 +03:00
|
|
|
CHECK( cbResultBufferSize >= SCSHIM_XXX_STATE_EXPORT_SIZE, "Export buffer too small" );
|
2018-11-17 03:28:12 +03:00
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxStateExport( &state.sc, pbResult );
|
|
|
|
*pcbResult = SCSHIM_XXX_STATE_EXPORT_SIZE;
|
2018-11-17 03:28:12 +03:00
|
|
|
SymCryptWipeKnownSize( &state.sc, sizeof( state.sc ) );
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxStateImport( &state.sc, pbResult );
|
2018-11-17 03:28:12 +03:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
VOID
|
|
|
|
algImpKeyPerfFunction< ImpXxx, AlgXxx>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T keySize )
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER( buf2 );
|
|
|
|
UNREFERENCED_PARAMETER( buf3 );
|
|
|
|
UNREFERENCED_PARAMETER( keySize );
|
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxInit( (SCSHIM_XXX_STATE *) buf1 );
|
2018-11-17 03:28:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
VOID
|
|
|
|
algImpDataPerfFunction<ImpXxx,AlgXxx>( PBYTE buf1, PBYTE buf2, PBYTE buf3, SIZE_T dataSize )
|
|
|
|
{
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxAppend( (SCSHIM_XXX_STATE *) buf1, buf2, dataSize );
|
|
|
|
SCSHIM_XxxResult( (SCSHIM_XXX_STATE *) buf1, buf3 );
|
2018-11-17 03:28:12 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
|
|
|
VOID
|
|
|
|
algImpCleanPerfFunction<ImpXxx,AlgXxx>( PBYTE buf1, PBYTE buf2, PBYTE buf3 )
|
|
|
|
{
|
|
|
|
UNREFERENCED_PARAMETER( buf2 );
|
|
|
|
UNREFERENCED_PARAMETER( buf3 );
|
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
SymCryptWipeKnownSize( buf1, sizeof( SCSHIM_XXX_STATE ) );
|
2018-11-17 03:28:12 +03:00
|
|
|
}
|
2022-08-05 23:01:21 +03:00
|
|
|
|
|
|
|
template<>
|
|
|
|
NTSTATUS HashImp<ImpXxx, AlgXxx>::initWithLongMessage( ULONGLONG nBytes )
|
|
|
|
{
|
2023-01-26 04:04:50 +03:00
|
|
|
// Discard this test for dynamic modules as it modifies state internals
|
|
|
|
if constexpr ( std::is_same<ImpXxx, ImpScDynamic>::value )
|
|
|
|
{
|
|
|
|
return STATUS_NOT_SUPPORTED;
|
|
|
|
}
|
2022-10-25 23:39:41 +03:00
|
|
|
|
2023-01-26 04:04:50 +03:00
|
|
|
//
|
|
|
|
// Long message initialization for MD/SHA family of hash functions.
|
|
|
|
// Needs to be guarded as not every hash state (e.g., SHA-3) has those members.
|
|
|
|
//
|
|
|
|
#ifdef SYMCRYPT_HASH_MD_SHA
|
|
|
|
memset( &state.sc.chain, 'b', sizeof( state.sc.chain ) );
|
|
|
|
state.sc.dataLengthL = nBytes;
|
|
|
|
state.sc.dataLengthH = 0;
|
|
|
|
state.sc.bytesInBuffer = nBytes % sizeof( state.sc.buffer );
|
2022-10-25 23:39:41 +03:00
|
|
|
#else
|
2023-01-26 04:04:50 +03:00
|
|
|
UNREFERENCED_PARAMETER( nBytes );
|
|
|
|
// We don't perform the long message test for non-MD/SHA algorithms,
|
|
|
|
// they should not have the 'Long' entry in the KAT file to trigger it.
|
|
|
|
// This block needs to be updated when the long message test is enabled
|
|
|
|
// for other hash functions in the future.
|
|
|
|
SymCryptFatal('lmsg');
|
2022-10-25 23:39:41 +03:00
|
|
|
#endif
|
2022-08-05 23:01:21 +03:00
|
|
|
|
2024-05-10 09:48:11 +03:00
|
|
|
SCSHIM_XxxStateCopy( &state.sc, &state.scHash.CONCAT2(ALG_name, State) );
|
2022-08-05 23:01:21 +03:00
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|