📄 stress.c
字号:
/****************************************************************************
* *
* cryptlib Test Code *
* Copyright Peter Gutmann 1995-2004 *
* *
****************************************************************************/
#ifdef _MSC_VER
#include "../cryptlib.h"
#include "test.h"
#else
#include "cryptlib.h"
#include "test/test.h"
#endif /* Braindamaged VC++ include handling */
#if defined( __MVS__ ) || defined( __VMCMS__ )
/* Suspend conversion of literals to ASCII. */
#pragma convlit( suspend )
#endif /* EBCDIC systems */
/* Define the following to perform a smoke test on the cryptlib kernel.
This includes:
Stress test: Create 10K objects and read/write some attributes
Data processing test: Encrypt/hash/MAC a buffer in a variable number
of variable-size blocks, then decrypt/hash/MAC with different
blocks and make sure the results match.
Kernel check test: Run through every possible object type and attribute
making sure we don't trigger any assertions.
Threading stress test: DES-encrypt 100 data blocks in threads.
Threading continuous test: Envelope data in threads until interrupted.
Note that these are exhaustive tests that check large numbers of objects
or parameter types and combinations so they can take some time to run to
completion */
/* #define SMOKE_TEST */
/****************************************************************************
* *
* Stress Test *
* *
****************************************************************************/
#ifdef SMOKE_TEST
#define NO_OBJECTS 10000 /* Can't exceed MAX_OBJECTS in cryptkrn.h */
static void testStressObjects( void )
{
CRYPT_HANDLE *handleArray = malloc( NO_OBJECTS * sizeof( CRYPT_HANDLE ) );
BYTE hash[ CRYPT_MAX_HASHSIZE ];
int i, length, status;
printf( "Running object stress test." );
assert( handleArray != NULL );
for( i = 0; i < NO_OBJECTS; i++ )
{
status = cryptCreateContext( &handleArray[ i ], CRYPT_UNUSED,
CRYPT_ALGO_SHA );
if( cryptStatusError( status ) )
printf( "cryptEncrypt() failed at %d with status %d.\n", i,
status );
}
printf( "." );
for( i = 0; i < NO_OBJECTS; i++ )
{
status = cryptEncrypt( handleArray[ i ], "12345678", 8 );
if( cryptStatusError( status ) )
printf( "cryptEncrypt() failed at %d with status %d.\n", i, status );
}
printf( "." );
for( i = 0; i < NO_OBJECTS; i++ )
{
status = cryptEncrypt( handleArray[ i ], "", 0 );
if( cryptStatusError( status ) )
printf( "cryptEncrypt() failed at %d with status %d.\n", i,
status );
}
printf( "." );
for( i = 0; i < NO_OBJECTS; i++ )
{
status = cryptGetAttributeString( handleArray[ i ],
CRYPT_CTXINFO_HASHVALUE, hash, &length );
if( cryptStatusError( status ) )
printf( "cryptEncrypt() failed at %d with status %d.\n", i,
status );
}
printf( "." );
for( i = 0; i < NO_OBJECTS; i++ )
{
status = cryptDestroyContext( handleArray[ i ] );
if( cryptStatusError( status ) )
printf( "cryptEncrypt() failed at %d with status %d.\n", i,
status );
}
free( handleArray );
puts( "." );
}
/****************************************************************************
* *
* Data Processing Test *
* *
****************************************************************************/
/* Data processing test */
#define DATABUFFER_SIZE 2048
#define MAX_BLOCKS 16
#define roundUp( size, roundSize ) \
( ( ( size ) + ( ( roundSize ) - 1 ) ) & ~( ( roundSize ) - 1 ) )
#ifdef __WINDOWS__
typedef int ( __stdcall *CRYPT_FUNCTION )( const CRYPT_CONTEXT cryptContext,
void *data, const int length );
#else
typedef int ( *CRYPT_FUNCTION )( const CRYPT_CONTEXT cryptContext,
void *data, const int length );
#endif /* __WINDOWS__ */
static int processData( const CRYPT_CONTEXT cryptContext, BYTE *buffer,
const int noBlocks, const int blockSize,
CRYPT_FUNCTION cryptFunction )
{
int offset = 0, i, status;
/* Encrypt the data in variable-length blocks. The technique for
selecting lengths isn't perfect since it tends to put large blocks
at the start and small ones at the end, but it's good enough for
general testing */
for( i = 0; i < noBlocks - 1; i++ )
{
int noBytes = rand() % ( DATABUFFER_SIZE - offset - \
( blockSize * ( noBlocks - i ) ) );
if( !noBytes )
noBytes = 1;
if( blockSize > 1 )
noBytes = roundUp( noBytes, blockSize );
status = cryptFunction( cryptContext, buffer + offset, noBytes );
if( cryptStatusError( status ) )
return( status );
offset += noBytes;
}
status = cryptFunction( cryptContext, buffer + offset,
DATABUFFER_SIZE - offset );
if( cryptStatusOK( status ) )
status = cryptFunction( cryptContext, "", 0 );
return( status );
}
static int testProcessing( const CRYPT_ALGO_TYPE cryptAlgo,
const CRYPT_MODE_TYPE cryptMode,
const CRYPT_QUERY_INFO cryptQueryInfo )
{
BYTE buffer1[ DATABUFFER_SIZE ], buffer2[ DATABUFFER_SIZE ];
BYTE hash1[ CRYPT_MAX_HASHSIZE ], hash2[ CRYPT_MAX_HASHSIZE ];
const int blockSize = ( cryptMode == CRYPT_MODE_ECB || \
cryptMode == CRYPT_MODE_CBC ) ? \
cryptQueryInfo.blockSize : 1;
int length1, length2, i;
/* Initialise the buffers with a known data pattern */
memset( buffer1, '*', DATABUFFER_SIZE );
memcpy( buffer1, "12345678", 8 );
memcpy( buffer2, buffer1, DATABUFFER_SIZE );
/* Process the data using various block sizes */
printf( "Testing algorithm %d, mode %d, for %d-byte buffer with\n block "
"count ", cryptAlgo, ( cryptMode == CRYPT_UNUSED ) ? 0 : cryptMode,
DATABUFFER_SIZE );
for( i = 1; i <= MAX_BLOCKS; i++ )
{
CRYPT_CONTEXT cryptContext;
int status;
memcpy( buffer1, buffer2, DATABUFFER_SIZE );
printf( "%d%s ", i, ( i == MAX_BLOCKS ) ? "." : "," );
/* Encrypt the data with random block sizes */
status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo );
if( cryptStatusError( status ) )
return( status );
if( cryptMode != CRYPT_UNUSED )
{
status = cryptSetAttribute( cryptContext, CRYPT_CTXINFO_MODE,
cryptMode );
if( cryptStatusError( status ) )
return( status );
if( cryptMode != CRYPT_MODE_ECB && cryptAlgo != CRYPT_ALGO_RC4 )
{
status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_IV,
"1234567887654321", cryptQueryInfo.blockSize );
if( cryptStatusError( status ) )
return( status );
}
}
if( cryptQueryInfo.keySize )
{
status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY,
"12345678876543211234567887654321",
cryptQueryInfo.keySize );
if( cryptStatusError( status ) )
return( status );
}
status = processData( cryptContext, buffer1, i, blockSize,
cryptEncrypt );
if( cryptStatusError( status ) )
return( status );
if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
{
status = cryptGetAttributeString( cryptContext,
CRYPT_CTXINFO_HASHVALUE, hash1, &length1 );
if( cryptStatusError( status ) )
return( status );
}
status = cryptDestroyContext( cryptContext );
if( cryptStatusError( status ) )
return( status );
/* Decrypt the data again with random block sizes */
status = cryptCreateContext( &cryptContext, CRYPT_UNUSED, cryptAlgo );
if( cryptStatusError( status ) )
return( status );
if( cryptMode != CRYPT_UNUSED )
{
status = cryptSetAttribute( cryptContext, CRYPT_CTXINFO_MODE,
cryptMode );
if( cryptStatusError( status ) )
return( status );
if( cryptMode != CRYPT_MODE_ECB && cryptAlgo != CRYPT_ALGO_RC4 )
{
status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_IV,
"1234567887654321", cryptQueryInfo.blockSize );
if( cryptStatusError( status ) )
return( status );
}
}
if( cryptQueryInfo.keySize )
{
status = cryptSetAttributeString( cryptContext, CRYPT_CTXINFO_KEY,
"12345678876543211234567887654321",
cryptQueryInfo.keySize );
if( cryptStatusError( status ) )
return( status );
}
status = processData( cryptContext, buffer1, i, blockSize,
cryptDecrypt );
if( cryptStatusError( status ) )
return( status );
if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
{
status = cryptGetAttributeString( cryptContext,
CRYPT_CTXINFO_HASHVALUE, hash2, &length2 );
if( cryptStatusError( status ) )
return( status );
}
status = cryptDestroyContext( cryptContext );
if( cryptStatusError( status ) )
return( status );
/* Make sure the values match */
if( cryptAlgo >= CRYPT_ALGO_FIRST_HASH )
{
if( ( length1 != length2 ) || memcmp( hash1, hash2, length1 ) )
{
puts( "Error: Hash value of identical buffers differs." );
return( -1234 );
}
}
else
if( memcmp( buffer1, buffer2, DATABUFFER_SIZE ) )
{
printf( "Decrypted data != encrypted data for algorithm %d.\n",
cryptAlgo );
return( -1234 );
}
}
printf( "\n" );
return( CRYPT_OK );
}
static void testDataProcessing( void )
{
CRYPT_QUERY_INFO cryptQueryInfo;
CRYPT_ALGO_TYPE cryptAlgo;
int errorCount = 0, status;
for( cryptAlgo = CRYPT_ALGO_FIRST_CONVENTIONAL;
cryptAlgo <= CRYPT_ALGO_LAST_CONVENTIONAL; cryptAlgo++ )
if( cryptStatusOK( cryptQueryCapability( cryptAlgo,
&cryptQueryInfo ) ) )
{
if( cryptAlgo != CRYPT_ALGO_RC4 )
{
status = testProcessing( cryptAlgo, CRYPT_MODE_ECB,
cryptQueryInfo );
if( cryptStatusError( status ) )
{
printf( "\nAlgorithm %d ECB mode processing failed with "
"status %d.\n", cryptAlgo, status );
errorCount++;
}
status = testProcessing( cryptAlgo, CRYPT_MODE_CBC,
cryptQueryInfo );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -